Plugin Directory

Changeset 3458877


Ignore:
Timestamp:
02/11/2026 10:42:09 AM (6 weeks ago)
Author:
filterdigital
Message:

Update to version 3.4.1 from GitHub

Location:
personalizewp
Files:
52 edited
1 copied

Legend:

Unmodified
Added
Removed
  • personalizewp/tags/3.4.1/README.txt

    r3452048 r3458877  
    44Requires at least: 6.2.0
    55Tested up to: 6.9
    6 Stable tag: 3.4.0
     6Stable tag: 3.4.1
    77Requires PHP: 7.4
    88License: GPL v3
     
    181181
    182182== Changelog ==
     183
     184= 3.4.1 =
     185
     186* Enhancement: Remove fixed authorisation nonces from use in JS, fixing potential 403 errors for heavily cached websites.
     187* Added: Back fill Teams for WooCommerce Memberships on all known visitors when upgrading.
     188* Bug fix: Undefined array keys 'scheme' and 'host' @props Paul Wong-Gibbs.
     189* Bug fix: Change export requests from showing a download link when underlying file has already been deleted.
     190* Bug fix: Fix translation issue causing pagination screen options to disappear on some admin screens.
     191* Bug fix: Fix issue causing Membership Teams columns and filters to disappear when not using US English language.
    183192
    184193= 3.4.0 =
  • personalizewp/tags/3.4.1/admin/class-data-export.php

    r3452048 r3458877  
    709709
    710710        // Only fully processed export requests have filenames.
    711         $filename = get_post_meta( $post_id, self::META_EXPORT_FILE, true );
     711        $filename = get_post_meta( $post_id, self::META_EXPORT_FILE, true );
    712712        if ( ! empty( $filename ) ) {
    713713            $export_dir = $this->get_export_directory();
     
    784784     */
    785785    public function cleanup_old_export_files(): void {
     786
    786787        $export_dir = $this->get_export_directory();
    787788        if ( ! $export_dir ) {
     
    789790        }
    790791
    791         $cutoff_date = strtotime( '-7 days' );
    792         $files       = glob( $export_dir . '/*.csv' );
    793 
    794         foreach ( $files as $file ) {
    795             if ( filemtime( $file ) < $cutoff_date ) {
    796                 wp_delete_file( $file );
    797             }
     792        // Get requests that are older than 7 days.
     793        $query_args = array(
     794            'post_type'      => self::POST_TYPE,
     795            'posts_per_page' => -1, // Need to get all
     796            'orderby'        => 'date',
     797            'order'          => 'DESC',
     798            'date_query'     => array(
     799                'before' => '-7 days',
     800            ),
     801            'meta_query'     => array(
     802                'has_file' => array(
     803                    'key'     => self::META_EXPORT_FILE,
     804                    'compare' => 'EXISTS',
     805                ),
     806            ),
     807        );
     808
     809        $query    = new \WP_Query();
     810        $requests = $query->query( $query_args );
     811
     812        foreach ( $requests as $export_request ) {
     813            // Doesn't matter what the status of the request is,
     814            // only that there is an export filename available.
     815            $filename = get_post_meta( $export_request->ID, self::META_EXPORT_FILE, true );
     816            if ( ! empty( $filename ) ) {
     817                $file_path = $export_dir . '/' . $filename;
     818
     819                if ( file_exists( $file_path ) ) {
     820                    wp_delete_file( $file_path );
     821                }
     822            }
     823
     824            // Always clear the export filename.
     825            delete_post_meta( $export_request->ID, self::META_EXPORT_FILE );
    798826        }
    799827    }
  • personalizewp/tags/3.4.1/admin/class-pageactivities.php

    r3452048 r3458877  
    7777        $screen = get_current_screen();
    7878
    79         $is_screen = is_object( $screen ) && 'personalize_page_' . self::SLUG === $screen->id;
     79        $is_screen = is_object( $screen ) && str_ends_with( $screen->id, self::SLUG );
    8080        if ( ! $is_screen ) {
    8181            return;
  • personalizewp/tags/3.4.1/admin/class-pagecategories.php

    r3452048 r3458877  
    109109        $screen = get_current_screen();
    110110
    111         $is_screen = is_object( $screen ) && 'admin_page_' . self::SLUG === $screen->id;
     111        $is_screen = is_object( $screen ) && str_ends_with( $screen->id, self::SLUG );
    112112        if ( ! $is_screen ) {
    113113            return;
  • personalizewp/tags/3.4.1/admin/class-pagecontacts.php

    r3452048 r3458877  
    9999        $screen = get_current_screen();
    100100
    101         $is_screen = is_object( $screen ) && 'admin_page_' . self::SLUG === $screen->id;
     101        $is_screen = is_object( $screen ) && str_ends_with( $screen->id, self::SLUG );
    102102        if ( ! $is_screen ) {
    103103            return;
  • personalizewp/tags/3.4.1/admin/class-pagedataexport.php

    r3452048 r3458877  
    8888        $screen = get_current_screen();
    8989
    90         $is_screen = is_object( $screen ) && 'admin_page_' . self::SLUG === $screen->id;
     90        $is_screen = is_object( $screen ) && str_ends_with( $screen->id, self::SLUG );
    9191        if ( ! $is_screen ) {
    9292            return;
  • personalizewp/tags/3.4.1/admin/class-pagerules.php

    r3452048 r3458877  
    9999        $screen = get_current_screen();
    100100
    101         $is_screen = is_object( $screen ) && 'personalize_page_' . self::SLUG === $screen->id;
     101        $is_screen = is_object( $screen ) && str_ends_with( $screen->id, self::SLUG );
    102102        if ( ! $is_screen ) {
    103103            return;
  • personalizewp/tags/3.4.1/admin/class-pagescoringrules.php

    r3452048 r3458877  
    122122        $screen = get_current_screen();
    123123
    124         $is_screen = is_object( $screen ) && 'personalize_page_' . self::SLUG === $screen->id;
     124        $is_screen = is_object( $screen ) && str_ends_with( $screen->id, self::SLUG );
    125125        if ( ! $is_screen ) {
    126126            return;
  • personalizewp/tags/3.4.1/admin/class-pagesegments.php

    r3452048 r3458877  
    113113        $screen = get_current_screen();
    114114
    115         $is_screen = is_object( $screen ) && 'personalize_page_' . self::SLUG === $screen->id;
     115        $is_screen = is_object( $screen ) && str_ends_with( $screen->id, self::SLUG );
    116116        if ( ! $is_screen ) {
    117117            return;
  • personalizewp/tags/3.4.1/admin/css/admin.css

    r3452048 r3458877  
    11@charset "UTF-8";
    2 /*! PersonalizeWP v3.4.0 | (c) 2026 PersonalizeWP | GPL-3.0 License */
     2/*! PersonalizeWP v3.4.1 | (c) 2026 PersonalizeWP | GPL-3.0 License */
    33body.pwp-page.pwp-fixed {
    44    position: fixed;
  • personalizewp/tags/3.4.1/admin/css/admin.min.css

    r3452048 r3458877  
    11@charset "UTF-8";
    2 /*! PersonalizeWP v3.4.0 | (c) 2026 PersonalizeWP | GPL-3.0 License */
     2/*! PersonalizeWP v3.4.1 | (c) 2026 PersonalizeWP | GPL-3.0 License */
    33body.pwp-page.pwp-fixed{position:fixed;min-width:100vw}body.pwp-page #wpcontent{padding-left:0 !important}body.pwp-page #screen-meta{margin-left:20px}body.pwp-page #screen-meta-links{margin-bottom:min(-40px,-3rem)}:where(#personalizewp){--color-dark: #1A1A1A;--color-light: #FCFCFF;--color-mid: #555;--color-mid-glare: #c4c4c4;--color-primary: #e1236c;--color-primary-shade: #8c003a;--color-primary-glare: #ffd9e0;--color-secondary: #002F5F;--color-secondary-shade: #001134;--color-secondary-glare: #d8e6f8;--required: #dc3545;accent-color:var(--color-primary);--color-text: #3c434a;--color-text-glare: #999;--color-text-link: var(--color-secondary);--color-text-link-hover: var(--color-primary);--color-nav-tab: var(--color-mid);--color-nav-tab-hover: var(--color-dark);--color-nav-tab-border: var(--color-secondary);--color-focus-ring: var(--color-primary);--color-warning-border: #d63638;--color-warning-background: var(--color-light);--color-success-border: #42BE65;--color-success-background: #DEFBE6;--color-info-border: var(--color-secondary);--color-info-background: #F5FAFF}:where(#personalizewp) *{box-sizing:border-box}:where(#personalizewp) svg{vertical-align:baseline}:where(#personalizewp) :is(h2,h3,h4,h5){margin-block-start:0;margin-block-end:.5rem;font-weight:500;line-height:1.2}:where(#personalizewp) h2{font-size:2rem}:where(#personalizewp) h3{font-size:1.75rem}:where(#personalizewp) h4{font-size:1.5rem}:where(#personalizewp) h5{font-size:1.25rem}:where(#personalizewp) p{margin-block:0}:where(#personalizewp) a{text-decoration:none;color:var(--color-text-link)}:where(#personalizewp) a:is(:hover,:focus-within){text-decoration:underline;color:var(--color-text-link-hover)}:where(#personalizewp) table{align-self:flex-start;flex-grow:1;flex-basis:0}:where(#personalizewp) table :where(th){font-weight:bold;text-align:inherit}:where(#personalizewp) table :where(th):not(.check-column,.column-cb){padding-inline-end:min(5vw,2rem);min-width:12ch}:where(#personalizewp) table :where(td):not(.check-column,.column-cb){min-width:15ch;word-break:break-all}:is(#personalizewp){clear:both;display:flex;flex-direction:column;background:var(--color-light);min-height:100vh;line-height:1.5;font-size:1rem;padding-inline:20px;padding-block-end:1em}:is(#personalizewp) a:where(.back){display:inline-flex;align-items:center;gap:4px}:is(#personalizewp) [hidden]{display:none !important}:is(#personalizewp) .row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}:is(#personalizewp) .col-12{position:relative;width:100%;padding-right:15px;padding-left:15px}@media(min-width: 992px){:is(#personalizewp) .col-lg-6{flex:0 0 50%;max-width:50%}}@media(min-width: 1200px){:is(#personalizewp) .col-xl-10{flex:0 0 83.33333333%;max-width:83.33333333%}}:is(#personalizewp) .mb-2{margin-bottom:.5rem !important}:is(#personalizewp) .mb-3{margin-bottom:1rem !important}:is(#personalizewp) .mb-4{margin-bottom:1.5rem !important}@media(min-width: 576px){:is(#personalizewp) .mb-sm-3{margin-bottom:1rem !important}}:is(#personalizewp) .with-sidebar{display:flex;flex-wrap:wrap;gap:var(--gutter, var(--gap-width, 1rem))}:is(#personalizewp) .with-sidebar:not([data-direction])>:first-child{flex-basis:var(--sidebar-target-width, 25rem);flex-grow:1}:is(#personalizewp) .with-sidebar:not([data-direction])>:last-child{flex-basis:0;flex-grow:999;min-inline-size:var(--sidebar-content-min-width, 50%)}:is(#personalizewp) .with-sidebar[data-direction=rtl]>:last-child{flex-basis:var(--sidebar-target-width, 25rem);flex-grow:1}:is(#personalizewp) .with-sidebar[data-direction=rtl]>:first-child{flex-basis:0;flex-grow:999;min-inline-size:var(--sidebar-content-min-width, 50%)}:is(#personalizewp) .cluster{display:flex;flex-wrap:wrap;gap:var(--gap-width, 0);justify-content:flex-start;align-items:center}:is(#personalizewp) .switcher{display:flex;flex-wrap:wrap;gap:var(--gap-width, 1rem);--threshold: 30rem}:is(#personalizewp) .switcher>*{flex-grow:1;flex-basis:calc((var(--threshold) - 100%)*999)}:is(#personalizewp) .stack{display:grid;grid-template-areas:"stack"}:is(#personalizewp) .stack>*{grid-area:stack}:is(#personalizewp) .flow>*+*{margin-block-start:var(--flow-space, 1em)}:is(#personalizewp) .grid{display:grid;gap:var(--gap-width, 0);grid-template-columns:repeat(var(--grid-auto, auto-fill), minmax(min(100%, var(--grid-min-width, 18rem)), 1fr))}:is(#personalizewp) .repel{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:var(--repel-vertical-alignment, center);gap:var(--gutter, var(--space-s))}:is(#personalizewp) .repel[data-nowrap]{flex-wrap:nowrap}:is(#personalizewp) :where([role=tablist],.nav-list){border-block-end:1px solid var(--color-mid-glare);list-style:"";margin-inline:0;margin-block:0 1.5rem;padding:0;display:flex;gap:var(--gap-width, 2rem);justify-content:flex-start;overflow-x:auto;scroll-behavior:smooth;scroll-snap-type:x proximity}:is(#personalizewp) :where([role=tablist],.nav-list):has(li a:focus-visible){outline:1px dotted var(--color-focus-ring)}:is(#personalizewp) :where([role=tablist],.nav-list) li{margin:0;padding:0;scroll-snap-align:start}:is(#personalizewp) :where([role=tablist],.nav-list) :where([role=tab],.nav-link){float:none;display:block;margin:0;padding-block:.25rem .75rem;padding-inline:0;text-decoration:none;color:var(--color-nav-tab);background-color:rgba(0,0,0,0);font-size:1.25rem;font-weight:600;box-shadow:none;border:none;border-block-end:2px solid rgba(0,0,0,0)}:is(#personalizewp) :where([role=tablist],.nav-list) :where([role=tab],.nav-link):where(:hover,:focus-visible,[aria-selected=true],.is-active){color:var(--color-nav-tab-hover);border-color:var(--color-nav-tab-border)}:is(#personalizewp) :where([role=tablist],.nav-list) :where([role=tab],.nav-link):where(:focus-visible){outline:2px solid var(--color-focus-ring);outline-offset:-2px}:is(#personalizewp)>header.header{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:1.625rem 1rem;margin-block-end:1rem;box-sizing:content-box;width:100%;margin-inline:-20px;padding-block:2.5rem;padding-inline:20px;background-color:#0b2146;background-image:url(../img/header-background.jpg);background-repeat:no-repeat;background-size:cover;background-position:center}:is(#personalizewp)>header.header .title{display:flex;gap:1rem;flex-wrap:wrap;align-items:center;justify-content:center;color:var(--color-light);font-weight:500;font-size:1.5rem;margin-block:0}:is(#personalizewp)>header.header .title .separator{font-weight:100}:is(#personalizewp)>header.header ul,:is(#personalizewp)>header.header li{margin:0}:is(#personalizewp)>header.header .nav-links{display:flex;gap:1rem;list-style:""}:is(#personalizewp)>header.header .nav-links .btn{display:flex;min-width:unset;min-height:unset;white-space:nowrap;background-color:var(--color-light);color:var(--color-secondary);border-color:var(--color-secondary);outline-color:var(--color-focus-ring);font-size:.9375rem;font-weight:600;transition:box-shadow .2s}:is(#personalizewp)>header.header .nav-links .btn:where(:hover,:focus-visible){box-shadow:0 .5rem 1rem rgba(0,0,0,.25);outline-offset:2px;outline-width:2px}@media(max-width: 991px){:is(#personalizewp)>header.header{justify-content:center}:is(#personalizewp)>header.header .nav-links{flex-wrap:wrap}}@media(max-width: 480px){:is(#personalizewp)>header.header .nav-links{flex-direction:column}}:is(#personalizewp) .header-nav{margin-block-end:2rem}:is(#personalizewp) :is(.notice,.notice-message){border-radius:4px;border-color:var(--fill, inherit);color:var(--color-dark)}:is(#personalizewp) :is(.notice,.notice-message).notice{margin-inline:0}:is(#personalizewp) :is(.notice,.notice-message).notice-message:not([class=notice-message]){background:var(--color-light);border:1px solid var(--fill, #c3c4c7);border-left-width:4px;box-shadow:0 1px 1px rgba(0,0,0,.04);padding:1px 12px}:is(#personalizewp) :is(.notice,.notice-message).notice-message:not([class=notice-message]) p{margin-block:.5em;padding:2px}:is(#personalizewp) :is(.notice,.notice-message):where(.notice-error,.notice-warning,.error-message){--fill: var(--color-warning-border);background-color:var(--color-warning-background)}:is(#personalizewp) :is(.notice,.notice-message):where(.notice-success,.success-message){--fill: var(--color-success-border);background-color:var(--color-success-background)}:is(#personalizewp) :is(.notice,.notice-message).notice-info{--fill: var(--color-info-border);background-color:var(--color-info-background)}:is(#personalizewp) :is(.notice,.notice-message) :where(.dashicons){margin-inline-end:.5em;color:var(--fill, inherit)}:is(#personalizewp) :is(.notice,.notice-message)>.dashicons{position:absolute;left:.5em;top:.5em}:is(#personalizewp) :is(.notice,.notice-message)>.dashicons~*{margin-left:2em}:is(#personalizewp) :is(.notice,.notice-message)>.dashicons~input{width:calc(100% - 2em)}:is(#personalizewp) .notice-message{position:relative;margin-inline:0}:is(#personalizewp) .alert{position:relative;font-size:.9375rem;line-height:1.6;border:1px solid rgba(0,0,0,0);border-radius:4px;border-left-width:4px;padding:.75rem 2rem;margin-block-end:0}:is(#personalizewp) .alert .close{padding:.5rem 1rem}:is(#personalizewp) .alert :where(.bi,.dashicons){position:absolute;left:.5em;top:.75em;color:var(--fill, inherit)}:is(#personalizewp) .alert>h2{font-size:15px;line-height:1.6;font-weight:600;margin-bottom:0;color:inherit}:is(#personalizewp) .alert>p{margin-bottom:0}:is(#personalizewp) .alert.alert-danger{--fill: #f5c6cb;background-color:#f8d7da;border-color:#f5c6cb;color:#721c24}:is(#personalizewp) .alert.alert-success{--fill: #42BE65;background-color:#defbe6;border-color:#42be65;color:#1a1a1a}:is(#personalizewp) .alert.alert-info{--fill: #0A1F43;background-color:#fff;border-color:#0a1f43;color:#1a1a1a}:is(#personalizewp) .alert p,:is(#personalizewp) .alert li{font-size:inherit;font-weight:400;line-height:1.6}:is(#personalizewp) .alert p:last-child{margin-bottom:0}:is(#personalizewp) .alert li{list-style-type:"- ";margin-left:1em}:is(#personalizewp) .notice~:where(.notice,.header-nav,main,.section:first-of-type){margin-block-start:2rem}:is(#personalizewp) .section+.section{margin-block-start:2rem}:is(#personalizewp) .section:last-of-type{padding-block-end:2rem}:is(#personalizewp) :where(.section-title,.dashboard-title){font-weight:500;margin-bottom:0;font-size:1.75rem}:is(#personalizewp) .section-subtitle{font-size:1.25rem}:is(#personalizewp) .section-description p{font-size:.9375rem;color:var(--color-dark);clear:both;margin-block-end:0}:is(#personalizewp) .section-description p+p{margin-block-start:1em}:is(#personalizewp) .required{color:var(--required)}:is(#personalizewp) :where(.categories,.rule-usage).with-sidebar{--sidebar-target-width: 28rem}:is(#personalizewp) :where(.profiles,.segments,.scoring-rules).with-sidebar{--sidebar-target-width: 28rem;--gutter: 1rem 2rem}:is(#personalizewp) :where(main).with-sidebar{--sidebar-content-min-width: 60%}:is(#personalizewp) .repel:has(.section-title){--gutter: 1rem 2rem}:is(#personalizewp) .section-description p{max-width:980px}:is(#personalizewp) .context-links{margin:0;display:flex;gap:2.5rem;align-items:center}:is(#personalizewp) .context-links li{margin:0}:is(#personalizewp) .contextual-link[inert]{color:var(--color-mid-glare)}:is(#personalizewp) label+:where(input,select){--flow-space: 0.25em}:is(#personalizewp) .vendor-copyrights{margin-block-start:auto;font-style:italic}:is(#personalizewp) :where(.btn,:where(a,button,input).button){border-radius:4px;border:none;place-content:center;align-items:flex-start;gap:.4em;font-size:1rem;line-height:1.8;text-decoration:none;transition-property:border,background,color;transition-duration:.15s;transition-timing-function:ease-in-out;cursor:pointer}:is(#personalizewp) :where(.btn,:where(a,button,input).button):not([hidden]){display:inline-flex;align-items:center}:is(#personalizewp) :where(.btn,:where(a,button,input).button):has(:where(.dashicons,.icon)){align-items:center;justify-content:flex-start}:is(#personalizewp) :where(.btn,:where(a,button,input).button):where(.btn,.primary,.button-primary,.secondary,.button-secondary){padding:.4rem 1rem;min-width:130px;min-height:42px}:is(#personalizewp) :where(.btn,:where(a,button,input).button):where(.primary,.button-primary){background-color:var(--color-primary);color:var(--color-light)}:is(#personalizewp) :where(.btn,:where(a,button,input).button):where(.primary,.button-primary):where(:hover,:focus):not([disabled]){background:var(--color-light);color:var(--color-primary);outline:2px solid var(--color-primary)}:is(#personalizewp) :where(.btn,:where(a,button,input).button):where(.alt-bg,.secondary,.button-secondary,:not(.primary,.button-primary)){background-color:var(--color-secondary);color:var(--color-light);font-size:.9rem;line-height:2}:is(#personalizewp) :where(.btn,:where(a,button,input).button):where(.alt-bg,.secondary,.button-secondary,:not(.primary,.button-primary)):where(:hover,:focus):not([disabled]){background:var(--color-light);color:var(--color-secondary);outline:2px solid var(--color-secondary)}:is(#personalizewp) :where(.btn,:where(a,button,input).button):where(.disabled,[disabled]){cursor:not-allowed;opacity:.65}:is(#personalizewp) :where(.btn,:where(a,button,input).button)+:where(.btn,.button){margin-left:.5rem}:is(#personalizewp) .chosen-container-single .chosen-single{padding:0 1.5rem 0 .75rem}:is(#personalizewp) [id=pwp-form]{max-width:95rem;display:flex;flex-direction:column}:is(#personalizewp) :is([id=pwp-form],.pwp-form) :where(label,.label){color:#000;font-size:.875rem;font-weight:600;display:flex;gap:.25em;align-items:center;margin-inline:unset;margin-block:0}:is(#personalizewp) :is([id=pwp-form],.pwp-form) :where(label,.label).nowrap{white-space:nowrap}:is(#personalizewp) :is([id=pwp-form],.pwp-form) :where(label,.label)+*{--flow-space: 0.5em}:is(#personalizewp) :is([id=pwp-form],.pwp-form) :where(label,.label)+:where(.description){margin:0;--flow-space: 0.25em}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .description+*{--flow-space: .75em}:is(#personalizewp) :is([id=pwp-form],.pwp-form) :where(.form-group,.conditions-container,.text-field-wrapper)>*+*{margin-top:var(--flow-space, 0.75em)}:is(#personalizewp) :is([id=pwp-form],.pwp-form) input{border-radius:4px;font-size:.875rem;line-height:1}:is(#personalizewp) :is([id=pwp-form],.pwp-form) input:not([type=submit]){padding:0 1.5rem .1em .75rem}:is(#personalizewp) :is([id=pwp-form],.pwp-form) input:not(.is-invalid):not(:invalid){border-color:var(--color-mid-glare)}:is(#personalizewp) :is([id=pwp-form],.pwp-form) input:disabled{background-color:#e9e9e9;position:relative;color:var(--color-dark);border:0}:is(#personalizewp) :is([id=pwp-form],.pwp-form) input:focus{outline:1px solid #0074e7;box-shadow:none}:is(#personalizewp) :is([id=pwp-form],.pwp-form) select{font-size:.875rem;line-height:2.5;border-radius:4px;padding:0 1.5rem 0 .75rem;height:auto;border:1px solid var(--color-mid-glare)}:is(#personalizewp) :is([id=pwp-form],.pwp-form) select:where(:disabled,[inert]){opacity:1;width:100%;background-color:#e9e9e9;position:relative;color:var(--color-dark);border:0}:is(#personalizewp) :is([id=pwp-form],.pwp-form) select:where(:disabled,[inert]).conditions-value{margin-right:0 !important}:is(#personalizewp) :is([id=pwp-form],.pwp-form) select:where(.is-invalid,:invalid)+.chosen-container .chosen-single{border-color:var(--required) !important}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition{display:flex;gap:1rem;align-items:flex-start}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition>*:not(label){width:min(100%,var(--max-input-width, 30rem))}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition[hidden]{display:none !important}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .field-wrapper-styles input{background-color:#fff;border-radius:4px;border-color:var(--color-mid-glare);box-shadow:none;display:flex;align-items:center}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .field-wrapper-styles input::placeholder{color:#444;opacity:.5}@media only screen and (max-width: 600px){:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .field-wrapper-styles input::placeholder{font-size:16px}}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .field-wrapper-styles input:where(:disabled,[inert]){background-color:#e9e9e9}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .field-wrapper-styles input:where(:disabled,[inert])::placeholder{color:var(--color-dark)}@media only screen and (max-width: 600px){:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .field-wrapper-styles input{box-shadow:none;border-color:#8c8f94;border-radius:3px}}@media only screen and (max-width: 600px){:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .field-wrapper-styles{margin-right:0;margin-bottom:10px}}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .days-field-wrapper{display:flex;align-items:center;gap:.75rem}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .days-field-wrapper .datepicker-field{flex:1;min-width:150px}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .days-field-wrapper .equals-sign{font-weight:600;font-size:1.125rem;color:var(--color-primary);flex-shrink:0}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .days-field-wrapper .field-days-number{width:100px;flex-shrink:0;text-align:center}@media only screen and (max-width: 600px){:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .days-field-wrapper{flex-direction:column;gap:.5rem}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .days-field-wrapper .equals-sign{display:none}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .days-field-wrapper .datepicker-field,:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .days-field-wrapper .field-days-number{width:100%;min-width:auto}}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition+*{--flow-space: 1em}:is(#personalizewp) :is([id=pwp-form],.pwp-form) :where([data-condition-count="0"] .condition,[data-condition-count="1"] .condition) .button-conditions-wrapper{visibility:hidden}:is(#personalizewp) .button-conditions-wrapper{display:flex;flex:0}:is(#personalizewp) .button-conditions-wrapper .remove-condition{cursor:pointer;display:flex;background:none;border:0;padding:0}:is(#personalizewp) .button-conditions-wrapper .remove-condition:disabled{opacity:.33;filter:grayscale(1)}:is(#personalizewp) .button-conditions-wrapper button:last-child{margin-right:0}:is(#personalizewp) .add-condition{color:var(--color-secondary);background:none;border:none;border-radius:4px;padding:.5em}:is(#personalizewp) .add-condition:where(:hover,:focus){color:var(--color-primary);cursor:pointer;outline:2px solid var(--color-primary)}:is(#personalizewp) .add-condition:focus-visible{outline:2px solid var(--color-primary)}:is(#personalizewp) .is-invalid~.invalid-feedback{display:block}:is(#personalizewp) .rule-message{color:var(--red);font-size:1rem}:is(#personalizewp) [id=form-actions]{margin-block-start:1.5rem}@media only screen and (max-width: 992px){:is(#personalizewp) .conditions .condition{flex-wrap:wrap}:is(#personalizewp) .conditions .condition>:not(label){margin-bottom:10px}}@media only screen and (max-width: 782px){:is(#personalizewp) .conditions .condition>:not(label){--max-input-width: 20rem}}@media only screen and (max-width: 600px){:is(#personalizewp) .conditions .condition>:not(label){--max-input-width: 100%}}:is(#personalizewp) .dashboard{padding-block:.5rem;--gutter: 2em}:is(#personalizewp) .dashboard:has(>aside.cta-sidebar){max-inline-size:100rem}:is(#personalizewp) .dashboard:has(>aside.cta-sidebar) :where(.pwp-tiles){max-inline-size:unset}:is(#personalizewp) .dashboard-title{border-bottom:1px solid var(--color-mid-glare);padding-bottom:10px;margin-bottom:1rem}:is(#personalizewp) .dashboard-description+*{margin-top:1.5rem}:is(#personalizewp) :where(.pwp-tiles){max-inline-size:68rem;--grid-min-width: 18rem;--gap-width: 2rem 1.5rem;padding-block-end:2rem}:is(#personalizewp) :where(.pwp-tiles).cta-sidebar{margin-inline:0;max-inline-size:unset;align-self:flex-start}:is(#personalizewp) :where(.pwp-tiles) :where(.tile){color:var(--color-dark);background:var(--color-light);box-shadow:0 1px 2px rgba(0,0,0,.15),0 0 2px rgba(0,0,0,.1);border-radius:.5rem;font-size:.875rem;position:relative;overflow:hidden}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) img{width:100%;aspect-ratio:1.77/1;object-fit:cover}:is(#personalizewp) :where(.pwp-tiles) :where(.tile).disabled img{filter:grayscale(1)}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .banner{z-index:1;place-self:center;font-size:.75rem;text-align:center;color:var(--color-light);font-weight:bold}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .banner.coming-soon{border-radius:3rem;background:var(--color-secondary);color:var(--color-light);padding:.5rem .75rem;text-transform:uppercase}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .banner.upgrade a{margin-top:0}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) :where(.tile__content){display:flex;flex-direction:column;padding-block:1rem 2rem;padding-inline:1rem}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) :where(.tile__content)>*{margin:0}:is(#personalizewp) :where(.pwp-tiles) :where(.tile):not(.has-button) .tile__content{padding-inline-end:2.5rem;padding-block-end:1rem}:is(#personalizewp) :where(.pwp-tiles) :where(.tile).has-button .tile__content{align-items:center;text-align:center}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .tile__title{color:inherit;font-size:.875rem;font-weight:bold}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .tile__title+*{--flow-space: .25rem}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .tile__title a{text-decoration:none}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .tile__title a::before{content:"";position:absolute;inset:0}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .tile__title a::after{content:"";position:absolute;bottom:2.5rem;right:.75rem;width:.6rem;height:.6rem;border-top:.15rem solid var(--color-text);border-right:.15rem solid var(--color-text);transform:rotate(45deg) translateX(-0.5rem) translateY(50%);transition:right .2s}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .tile__title a:where(:hover,:focus-within)::after{right:.25rem}:is(#personalizewp) :where(.pwp-tiles) :where(.tile).has-button .tile__title{color:var(--color-dark);font-size:1.25rem}:is(#personalizewp) :where(.pwp-tiles) :where(.tile):where(.disabled,[inert]) .tile__title{color:var(--color-mid-glare)}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .btn{--flow-space: 1.5rem}:is(#personalizewp) ajax-form{display:block}:is(#personalizewp) [data-tabs]+*{clear:both}:is(#personalizewp) :where(.pwp-panel,ajax-form){padding:min(5vw,2rem);box-shadow:0 1px 2px rgba(0,0,0,.15),0 0 2px rgba(0,0,0,.1);border-radius:4px;background:var(--color-light, #fff);--flow-space: initial}:is(#personalizewp) :where(.pwp-panel,ajax-form)>*{max-width:55rem}:is(#personalizewp) :where(.pwp-panel,ajax-form):not(:last-child){margin-bottom:3rem}:is(#personalizewp) :where(.pwp-panel,ajax-form) :where(.pwp-panel__title,h2){margin-bottom:1.5rem;font-size:1.25rem}:is(#personalizewp) :where(.pwp-panel,ajax-form)>.section-description+*{margin-top:2rem}:is(#personalizewp) :where(.pwp-panel,ajax-form) .form-table p.description{word-break:initial;margin-top:8px}:is(#personalizewp) :where(.pwp-panel,ajax-form) .form-table p.description:first-child{margin-top:0}:is(#personalizewp) :where(.pwp-panel,ajax-form) .form-table th{padding-block:15px;width:18ch}:is(#personalizewp) :where(.pwp-panel,ajax-form) .form-table th label{font-size:1rem;text-wrap:balance}:is(#personalizewp) form .cluster{--gap-width: 1rem}:is(#personalizewp) form .switcher :where(.email,:has(input[type=email])){--threshold: 60rem}:is(#personalizewp) form .switcher :where(.email,:has(input[type=email])) input[type=email]{width:100%}:is(#personalizewp) form label{display:block}:is(#personalizewp) form label a:not(:hover,:focus-within){color:var(--color-secondary)}:is(#personalizewp) form :is(input[type=text],input[type=number],input[type=email],input[type=password],select,textarea){border-color:var(--color-mid-glare);width:min(100%,var(--max-input-width, 40rem));min-height:2.625rem;max-width:unset}:is(#personalizewp) form input.search-icon{background-image:url("../img/search-icon.svg") !important;background-repeat:no-repeat;background-position:center left 8px;padding-left:40px !important}:is(#personalizewp) form .field-error input,:is(#personalizewp) form .field-error textarea{border-color:#d00}:is(#personalizewp) form .input-error{font-size:75%;color:#d00}:is(#personalizewp) form .actions{display:flex;gap:.5em;align-items:flex-start}:is(#personalizewp) .entity-panel{padding-block-end:1px}:is(#personalizewp) .entity-panel>*+*{margin-block-start:var(--flow-space, 3em)}:is(#personalizewp) .entity-panel__nav+*{--flow-space: 1em}:is(#personalizewp) .entity-panel__header{margin-bottom:1rem}:is(#personalizewp) .entity-panel__header h2{margin:0}:is(#personalizewp) .entity-panel .subheading{color:var(--color-text-glare);font-size:1.15em}:is(#personalizewp) .entity-panel table{table-layout:fixed;border-collapse:collapse}:is(#personalizewp) .entity-panel table tr :where(th):not(.check-column,.column-cb){font-weight:bold;padding-right:min(5vw,2rem);min-width:12ch}:is(#personalizewp) .entity-panel table tr :where(td):not(.check-column,.column-cb){min-width:15ch;word-break:break-all}:is(#personalizewp) .entity-panel table tr:not(:last-child) :where(th,td):not(.check-column,.column-cb){padding-bottom:1rem}:is(#personalizewp) .entity-panel input[type=number]{max-width:40ch}:is(#personalizewp) .entity-panel .form-control{max-width:100%}:is(#personalizewp) .entity-panel .form-control.is-invalid+.invalid-feedback{display:block}:is(#personalizewp) .entity-panel .profile-fields table th:first-child{width:35%}:is(#personalizewp) .profile.with-sidebar{--sidebar-target-width: 8.5rem;--sidebar-content-min-width: 75%}:is(#personalizewp) .profile.with-sidebar .profile-fields{max-width:unset !important;align-items:flex-start !important;--gap-width: 1rem;--flow-space: 1.5em}:is(#personalizewp) .profile.with-sidebar .profile-fields>*+*{margin-block-start:var(--flow-space, 2em);margin-block-end:0}:is(#personalizewp) .profile.with-sidebar .lead_score{background:var(--color-secondary-glare);padding:1rem;align-self:flex-start;display:flex;flex-direction:column;text-align:center;gap:.5rem}:is(#personalizewp) .profile.with-sidebar .lead_score h3{font-size:1rem;margin:0}:is(#personalizewp) .profile.with-sidebar .lead_score p{font-size:1.75rem;font-weight:600;margin-block:0}:is(#personalizewp) auto-complete .search{display:flex;position:relative}:is(#personalizewp) auto-complete .search>button{position:absolute;right:0;top:0;bottom:0;border:none;background-color:rgba(0,0,0,0);display:grid;place-content:center}:is(#personalizewp) auto-complete .components-spinner{overflow:visible}:is(#personalizewp) auto-complete .components-spinner path{transform-origin:50% 50% 0px;animation:1.4s linear 0s infinite normal both running rotate-360}:is(#personalizewp) auto-complete .search-results{font-size:.875em;border-radius:4px;background:#fff;box-shadow:0px 0px 4px 0px rgba(0,0,0,.05),0px 4px 8px 0px rgba(0,0,0,.2);max-height:350px;overflow-y:auto;list-style:"" !important;display:flex;flex-flow:column;gap:4px;padding-block:.5em;position:relative;z-index:1000}:is(#personalizewp) auto-complete .search-results:empty{opacity:0;margin-block:0;padding-block:0}:is(#personalizewp) auto-complete .search-results .nothing,:is(#personalizewp) auto-complete .search-results .components-spinner{margin-inline-start:1rem}:is(#personalizewp) auto-complete .search-results li{margin:0;padding:0}:is(#personalizewp) auto-complete .search-results button{cursor:pointer;width:100%;display:flex;flex-direction:column;align-items:flex-start;text-align:left;gap:4px;padding-block:.5rem;padding-inline:1rem;border:none}:is(#personalizewp) auto-complete .search-results button:not(:hover,:focus){background:rgba(0,0,0,0)}:is(#personalizewp) auto-complete .search-results button .header{font-weight:600}:is(#personalizewp) auto-complete .search-results button .info{font-style:italic;padding-inline-start:1em}:is(#personalizewp) auto-complete .search-results [data-type=load-more]{text-align:center;align-items:center;width:max-content;margin-inline:auto}:is(#personalizewp) auto-complete .tag-list:not(:empty){--flow-space: 1rem}:is(#personalizewp) custom-tag-list{--max-input-width: 30rem;display:block}:is(#personalizewp) :where(.tag-list){display:flex;margin:0;margin-block-start:var(--flow-space, 0);--gap-width: 1rem}:is(#personalizewp) :where(.tag-list) :where(li,.tag){list-style:"";display:flex;gap:.25rem;align-items:center;border:none;border-radius:5rem;background-color:var(--color-secondary-glare);color:var(--color-dark);font-size:.875rem;margin:0;padding-block:.25rem;padding-inline:1rem;min-height:2.5rem}:is(#personalizewp) :where(.tag-list) :where(li,.tag) button:not([hidden]){margin-inline-end:-0.75rem}:is(#personalizewp) :where(.tag-list) :where(li,.tag):has(button:where(:hover,:focus),a.trash:where(:hover,:focus)){background-color:var(--color-light);color:var(--color-secondary);outline:2px solid var(--color-secondary)}:is(#personalizewp) :where(.tag-list) :where(li,.tag) a.trash:focus-visible{outline-color:var(--color-primary)}:is(#personalizewp) :where(.tag-list) :where(button,a.trash){min-height:2rem;display:flex;align-items:center}:is(#personalizewp) :where(.tag-list) button,:is(#personalizewp) :where(.tag-list) label{cursor:pointer;margin-block:0}:is(#personalizewp) :where(.tag-list) button{border:none;outline-color:rgba(0,0,0,0);background:rgba(0,0,0,0);color:currentColor;fill:currentColor;padding:0;box-shadow:none}:is(#personalizewp) dialog{border:none;padding:0;animation:dialog-fade-out .25s ease-out}:is(#personalizewp) dialog:not(.onboarding){background-color:var(--color-light);box-shadow:0 0 16px 0 rgba(0,0,0,.25);border-radius:.3rem;width:min(30rem,80%)}:is(#personalizewp) dialog[open]{animation:dialog-fade-in .25s ease-out}:is(#personalizewp) dialog::backdrop{animation:dialog-backdrop-fade-in .25s ease-out forwards;background-color:rgba(0,0,0,.5)}:is(#personalizewp) dialog>*{padding:1rem}:is(#personalizewp) dialog form{display:block}:is(#personalizewp) dialog .dialog-header{display:flex;justify-content:space-between;align-items:flex-start;margin-block-start:0}:is(#personalizewp) dialog .dialog-header :where(button,[type=submit]){cursor:pointer;background-color:rgba(0,0,0,0);border:0;border-radius:.3rem;outline-color:rgba(0,0,0,0);font-size:1.5rem;font-weight:700;line-height:1;color:var(--color-dark);text-shadow:0 1px 0 var(--color-light);opacity:.5;padding:calc(1rem - 4px);margin:calc(-1rem + 4px)}:is(#personalizewp) dialog .dialog-header :where(button,[type=submit]):where(:focus-within,:hover){color:var(--color-dark);opacity:.75}:is(#personalizewp) dialog .dialog-header+*{margin-block-start:var(--flow-space, 1em)}:is(#personalizewp) .table-actions{align-self:flex-end;display:flex;align-items:stretch;flex-wrap:wrap;gap:1.5rem 1rem;justify-content:flex-start}:is(#personalizewp) .table-actions.sidebar{justify-content:flex-end}:is(#personalizewp) .table-actions .search-box{margin-block:0;display:flex;gap:.5rem;align-items:stretch;justify-content:center;flex-wrap:wrap}:is(#personalizewp) .table-actions .search-box input{width:auto}:is(#personalizewp) .table-actions .button,:is(#personalizewp) .table-actions .btn{margin:0}:is(#personalizewp) .table-actions :is(.button,.btn,input[type=text],input[type=submit]){min-height:42px}:is(#personalizewp) .tablenav{display:flex;margin-block:1em;margin-inline:0;padding:0;flex-wrap:wrap;gap:.5em 0;height:auto;justify-content:start;align-items:end}:is(#personalizewp) .tablenav .actions{display:flex;gap:.5em;align-items:stretch}:is(#personalizewp) .tablenav input{width:auto !important;min-height:unset !important}:is(#personalizewp) .tablenav :is(input[type=submit]){min-height:42px}:is(#personalizewp) .tablenav :is(.category-dropdown){border-radius:4px;min-height:42px;border:1px solid var(--color-mid-glare);min-width:12.5em;font-size:.875rem;margin-right:0}:is(#personalizewp) .tablenav .tablenav-pages{float:none;margin-inline-start:auto;margin-block:0}@media screen and (min-width: 783px){:is(#personalizewp) .tablenav .pagination-links{display:inline-flex;align-items:baseline;gap:4px}}:is(#personalizewp) .tablenav .button{background-color:rgba(0,0,0,0);color:inherit;border:1px solid var(--color-secondary)}:is(#personalizewp) .tablenav .button:not(:where([disabled],.disabled)):where(:hover,:focus){border-color:var(--color-primary);outline:2px solid var(--color-primary)}:is(#personalizewp) .subsubsub{margin:0}:is(#personalizewp) .subsubsub li a{border:1px solid var(--border-color, var(--color-mid-glare));font-size:.875rem;display:inline-block;padding-inline:1rem;padding-block:.3125rem}:is(#personalizewp) .subsubsub li a:where(:hover,:focus-visible,.current){background:var(--color-primary-glare);text-decoration:none}:is(#personalizewp) .subsubsub li a:where(:focus-visible){outline-color:var(--color-primary)}:is(#personalizewp) .subsubsub li a.current{--border-color: var(--color-primary)}:is(#personalizewp) .subsubsub li:first-of-type a{border-start-start-radius:4px;border-end-start-radius:4px}:is(#personalizewp) .subsubsub li:first-of-type a:not(.current){border-inline-end-width:0}:is(#personalizewp) .subsubsub li:last-of-type a{border-start-end-radius:4px;border-end-end-radius:4px}:is(#personalizewp) .subsubsub li:last-of-type a:not(.current){border-inline-start-width:0}@media screen and (min-width: 1100px){:is(#personalizewp) .column-usage_blocks,:is(#personalizewp) .column-activity_type,:is(#personalizewp) .column-contact_count,:is(#personalizewp) .column-created{width:20ch}:is(#personalizewp) .column-lead_score{width:15ch}}:is(#personalizewp) .wp-list-table{border:1px solid rgba(0,0,0,.1);border-radius:4px;border-collapse:separate !important}:is(#personalizewp) .wp-list-table.api_key_table{margin-block-start:1rem;margin-block-end:2rem}:is(#personalizewp) .wp-list-table.api_key_table caption{font-weight:bold;color:inherit;caption-side:top;padding-block:.75em;text-align:start}:is(#personalizewp) .wp-list-table th,:is(#personalizewp) .wp-list-table td{font-size:.9375rem}:is(#personalizewp) .wp-list-table th:where(.column-count),:is(#personalizewp) .wp-list-table td:where(.column-count){text-align:center}:is(#personalizewp) .wp-list-table th{font-weight:700}:is(#personalizewp) .wp-list-table th:not(.check-column,.column-cb){padding-block:1rem;padding-inline:1rem}:is(#personalizewp) .wp-list-table th:where(.sortable,.sorted) a{padding:0;color:inherit}:is(#personalizewp) .wp-list-table th:where(.column-count) a{display:flex;justify-content:center}:is(#personalizewp) .wp-list-table th:where(.column-count) a>span{float:none}:is(#personalizewp) .wp-list-table th:where(.column-lead_score,.column-contact_count) a{display:flex;justify-content:center}:is(#personalizewp) .wp-list-table th:where(.column-lead_score,.column-contact_count) a>span{float:none}@media screen and (min-width: 783px){:is(#personalizewp) .wp-list-table td:not(.check-column,.column-cb){padding-block:.5rem;padding-inline:1rem}:is(#personalizewp) .wp-list-table td:where(.column-lead_score,.column-contact_count){text-align:center}}:is(#personalizewp) .wp-list-table tbody tr:hover{background-color:#f8f8f8}:is(#personalizewp) .wp-list-table tbody>:nth-child(2n+1){background-color:inherit}:is(#personalizewp) .wp-list-table tbody>:not(:last-child)>:where(th,td){border-bottom:1px solid var(--color-mid-glare)}:is(#personalizewp) dialog.onboarding{height:100vh;width:100vw}:is(#personalizewp) dialog.onboarding .wrapper{padding:0;height:100%;width:100%;display:grid;grid-template-areas:"aside main" "aside footer";grid-template-columns:0px auto;grid-template-rows:1fr auto}@media(min-width: 768px){:is(#personalizewp) dialog.onboarding .wrapper{grid-template-columns:112px auto}}:is(#personalizewp) dialog.onboarding .wrapper aside{grid-area:aside}:is(#personalizewp) dialog.onboarding .wrapper article{grid-area:main}:is(#personalizewp) dialog.onboarding .wrapper>footer{grid-area:footer}:is(#personalizewp) dialog.onboarding aside{display:flex;justify-content:center;align-items:center;color:var(--color-light, #fff);background-color:var(--color-secondary);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='92' height='146' fill='none' viewBox='0 0 92 146'%3E%3Ccircle cx='73' cy='73' r='73' fill='url(%23pink_shape)' transform='matrix(0 -1 -1 0 92 146)'/%3E%3CradialGradient id='pink_shape' cx='0' cy='0' r='1' gradientTransform='rotate(139 112 19) scale(215)' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%23D300A5'/%3E%3Cstop offset='1' stop-color='%23542A73' stop-opacity='0'/%3E%3C/radialGradient%3E%3C/svg%3E%0A");background-repeat:no-repeat;background-position:bottom left;overflow:hidden}:is(#personalizewp) dialog.onboarding aside nav form{display:flex;place-content:center;align-items:center;margin-block-end:1rem}:is(#personalizewp) dialog.onboarding aside nav form button{border-color:rgba(138,141,143,.2)}:is(#personalizewp) dialog.onboarding aside nav button{display:flex;border:2px solid rgba(0,0,0,0);background-color:rgba(0,0,0,0);color:inherit;aspect-ratio:1;padding:.5em}:is(#personalizewp) dialog.onboarding aside nav button[disabled]{cursor:auto;opacity:inherit;border-color:rgba(0,0,0,0) !important;background-color:rgba(0,0,0,0) !important;color:inherit !important}:is(#personalizewp) dialog.onboarding aside nav button:where(:hover,:focus-visible):not([disabled]){border-color:rgba(138,141,143,.6)}:is(#personalizewp) dialog.onboarding aside nav button:where(:hover,:focus-visible):not([disabled]) svg{opacity:.6 !important}:is(#personalizewp) dialog.onboarding article{padding:0;display:flex}:is(#personalizewp) dialog.onboarding section{flex:1;display:flex;flex-direction:column}:is(#personalizewp) dialog.onboarding section>*{padding-block:2rem;padding-inline:clamp(1.25rem,.6875rem + 2.8125vi,3.5rem)}:is(#personalizewp) dialog.onboarding header{display:flex;gap:1rem;align-items:start;min-height:10rem;background-color:var(--color-secondary-glare);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='526' height='220' fill='none' viewBox='0 0 526 220'%3E%3Cg fill-opacity='.1' opacity='.4'%3E%3Cpath fill='url(%23grey_shape1)' d='M321 110 232-48A124 124 0 1 0 16 74l90 158a124 124 0 1 0 215-122Z'/%3E%3Cpath fill='url(%23grey_shape2)' d='M403 178a123 123 0 1 0 0-246 123 123 0 0 0 0 246Z'/%3E%3C/g%3E%3Cdefs%3E%3CradialGradient id='grey_shape1' cx='0' cy='0' r='1' gradientTransform='matrix(173 -173 144 144 87 295)' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%230A1F43'/%3E%3Cstop offset='1' stop-color='%230A1F43' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='grey_shape2' cx='0' cy='0' r='1' gradientTransform='matrix(129 -129 120 120 343 178)' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%230A1F43'/%3E%3Cstop offset='1' stop-color='%230A1F43' stop-opacity='0'/%3E%3C/radialGradient%3E%3C/defs%3E%3C/svg%3E%0A");background-repeat:no-repeat;background-position:bottom right}:is(#personalizewp) dialog.onboarding header h1{font-size:1.75rem}:is(#personalizewp) dialog.onboarding header img,:is(#personalizewp) dialog.onboarding header svg{flex-shrink:0;margin-inline-start:auto}:is(#personalizewp) dialog.onboarding .content{flex:1}:is(#personalizewp) dialog.onboarding .content :where(img){display:block;max-width:100%;width:100%;height:auto}:is(#personalizewp) dialog.onboarding .content :where(p){margin-bottom:0}:is(#personalizewp) dialog.onboarding .content :where(p):not([class]){max-width:70ch}:is(#personalizewp) dialog.onboarding .content :where(iframe){width:100%;height:auto;aspect-ratio:16/9}:is(#personalizewp) dialog.onboarding .content :where(label,.label){font-weight:normal}:is(#personalizewp) dialog.onboarding :where(.onboard-cards){--gap-width: 1.75rem;--grid-auto: auto-fit;--grid-min-width: min(40%, 16rem);margin-block:2rem}:is(#personalizewp) dialog.onboarding :where(.onboard-cards):has(:nth-child(4)){--grid-min-width: min(40%, 10rem)}:is(#personalizewp) dialog.onboarding :where(.onboard-cards) :where(.onboard-card){display:flex;flex-direction:column;align-items:center;text-align:center}:is(#personalizewp) dialog.onboarding .switcher.onboard-cards{--threshold: 40rem}:is(#personalizewp) dialog.onboarding .stack.video{width:min(100%,45rem);margin-inline:auto;margin-block-start:1em;overflow:hidden;border-radius:1.5rem;box-shadow:0px 2px 1.5rem -4px rgba(10,31,67,.2)}:is(#personalizewp) dialog.onboarding .stack.video .overlay{order:1;display:grid;place-content:center}:is(#personalizewp) dialog.onboarding .stack.video button{aspect-ratio:1;padding:20px;border:none;border-radius:50%;background:linear-gradient(90deg, #C127A0 0%, #F20FA6 100%)}:is(#personalizewp) dialog.onboarding .stack.video button:where(:hover,:focus){border:4px solid var(--color-light, #fff);outline:2px solid rgba(0,0,0,0)}:is(#personalizewp) dialog.onboarding .stack.video button svg{max-height:100%;width:auto;transform:translateX(2px)}:is(#personalizewp) dialog.onboarding img.aligncenter{max-width:min(28rem,70vw);margin-inline:auto}:is(#personalizewp) dialog.onboarding footer.next-step{margin-block-start:auto;padding-block-end:0;display:flex;place-content:center}:is(#personalizewp) dialog.onboarding .cluster.checkmarks{--gap-width: 0}:is(#personalizewp) dialog.onboarding label.checkmark{cursor:pointer;margin:0;display:flex;gap:.4em;justify-content:center;align-items:center;width:auto;padding-block:.375rem;padding-inline:1.5rem .75rem;border:1px solid #ced4da;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}:is(#personalizewp) dialog.onboarding label.checkmark:first-child{border-top-left-radius:40px;border-bottom-left-radius:40px}:is(#personalizewp) dialog.onboarding label.checkmark:not(:last-child){border-right-color:rgba(0,0,0,0)}:is(#personalizewp) dialog.onboarding label.checkmark:last-child{border-top-right-radius:40px;border-bottom-right-radius:40px}:is(#personalizewp) dialog.onboarding label.checkmark input{clip:rect(1px, 1px, 1px, 1px);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}:is(#personalizewp) dialog.onboarding label.checkmark input:before{display:none}:is(#personalizewp) dialog.onboarding label.checkmark svg{opacity:0;flex-shrink:0}:is(#personalizewp) dialog.onboarding label.checkmark:focus-within{outline:max(2px,.15em) solid currentColor;outline-offset:max(2px,.15em)}:is(#personalizewp) dialog.onboarding label.checkmark:where(:hover,:focus-within) svg{opacity:.2}:is(#personalizewp) dialog.onboarding label.checkmark:has(input:checked){background-color:rgba(193,39,160,.25);border-color:#000}:is(#personalizewp) dialog.onboarding label.checkmark:has(input:checked) svg{opacity:1}:is(#personalizewp) dialog.onboarding form{margin:0;padding:0;box-shadow:none;background-color:rgba(0,0,0,0);max-width:45rem}:is(#personalizewp) dialog.onboarding :where(.wizard-progress){display:flex;place-content:center;align-items:center;margin:0;padding:0;list-style:""}:is(#personalizewp) dialog.onboarding :where(.wizard-progress) li{margin:0}:is(#personalizewp) dialog.onboarding :where(.wizard-progress).icons{flex-direction:column;gap:.25rem;--line-width: .3125rem}:is(#personalizewp) dialog.onboarding :where(.wizard-progress).icons li+li:before{display:block;content:"";position:relative;top:0;left:calc(50% - var(--line-width)/2);width:var(--line-width);height:2rem;background-color:rgba(138,141,143,.2);border-radius:calc(var(--line-width)/2)}:is(#personalizewp) dialog.onboarding :where(.wizard-progress).icons li:where(:not(.is-active,:focus-within)) svg{opacity:.2}:is(#personalizewp) dialog.onboarding :where(.wizard-progress).dots{padding-block:2rem;gap:1rem;--line-width: 1.25rem;--line-height: .625rem;--line-color: #d9d9d9}:is(#personalizewp) dialog.onboarding :where(.wizard-progress).dots li{height:var(--line-height);width:var(--line-width);border-radius:calc(var(--line-height)/2);background-color:var(--line-color);color:var(--line-color);transition:all 300ms ease}:is(#personalizewp) dialog.onboarding :where(.wizard-progress).dots li:where(.is-active){--line-width: 3.75rem;--line-color: #C127A0}:is(#personalizewp) .discount-offer-block{background-color:#f10fa6 !important;margin-top:-1rem;margin-top:-1rem;padding:1rem 1.5rem;display:flex;flex-direction:row;justify-content:center;align-items:center;margin-bottom:1rem}:is(#personalizewp) .discount-offer-block .discount-offer-text{color:#fff;margin-bottom:0;text-align:center;line-height:1.5rem}:is(#personalizewp) .discount-offer-block .discount-offer-text a{color:#fff !important;text-decoration:none !important;border-bottom:1px solid #fff;padding-bottom:2px}:is(#personalizewp) .discount-offer-block .discount-offer-text a:hover{cursor:pointer !important}@keyframes rotate-360{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes dialog-fade-in{0%{opacity:0;transform:translateY(-2rem);display:none}100%{opacity:1;transform:translateY(0);display:block}}@keyframes dialog-fade-out{0%{opacity:1;transform:translateY(0);display:block}100%{opacity:0;transform:translateY(-2rem);display:none}}@keyframes dialog-backdrop-fade-in{0%{background-color:rgba(0,0,0,0)}100%{background-color:rgba(0,0,0,.5)}}
  • personalizewp/tags/3.4.1/admin/css/editor-content.css

    r3452048 r3458877  
    11@charset "UTF-8";
    2 /*! PersonalizeWP v3.4.0 | (c) 2026 PersonalizeWP | GPL-3.0 License */
     2/*! PersonalizeWP v3.4.1 | (c) 2026 PersonalizeWP | GPL-3.0 License */
    33.personalizewp__has-been-personalized {
    44    outline: 2px dashed rgb(241, 15, 166);
  • personalizewp/tags/3.4.1/admin/css/editor-content.min.css

    r3452048 r3458877  
    11@charset "UTF-8";
    2 /*! PersonalizeWP v3.4.0 | (c) 2026 PersonalizeWP | GPL-3.0 License */
     2/*! PersonalizeWP v3.4.1 | (c) 2026 PersonalizeWP | GPL-3.0 License */
    33.personalizewp__has-been-personalized{outline:2px dashed #f10fa6}.personalizewp__has-been-personalized::before{content:attr(data-personalized-label);display:inline-block;position:absolute;inset-block-start:-1rem;inset-inline-start:-0.15rem;background-color:rgba(241,15,66,.15);border-top-left-radius:1rem;color:#000;font-size:.5rem;line-height:normal;padding-block:.25em;padding-inline:1em;padding-inline-start:calc(.625rem + 1px);pointer-events:none}:is(*.is-selected+.personalizewp__has-been-personalized,.personalizewp__has-been-personalized.is-selected)::before{display:none}pwp-user-data:not(:defined){outline:2px dashed hotpink;position:relative}pwp-user-data:not(:defined)::before{content:"PWP:" attr(data);display:block;position:absolute;inset-block-start:-1.5em;inset-inline-end:0;background-color:#fff;color:#d3d3d3;padding:0 2px;font-size:10px;font-style:italic}
  • personalizewp/tags/3.4.1/admin/css/editor.css

    r3452048 r3458877  
    11@charset "UTF-8";
    2 /*! PersonalizeWP v3.4.0 | (c) 2026 PersonalizeWP | GPL-3.0 License */
     2/*! PersonalizeWP v3.4.1 | (c) 2026 PersonalizeWP | GPL-3.0 License */
    33.components-panel input:is([type=url], [type=email], [type=number]):where(:disabled, .disabled) {
    44    background-color: var(--wp-components-color-gray-100, #f0f0f0);
  • personalizewp/tags/3.4.1/admin/css/editor.min.css

    r3452048 r3458877  
    11@charset "UTF-8";
    2 /*! PersonalizeWP v3.4.0 | (c) 2026 PersonalizeWP | GPL-3.0 License */
     2/*! PersonalizeWP v3.4.1 | (c) 2026 PersonalizeWP | GPL-3.0 License */
    33.components-panel input:is([type=url],[type=email],[type=number]):where(:disabled,.disabled){background-color:var(--wp-components-color-gray-100, #f0f0f0);border-color:var(--wp-components-color-gray-400, #ccc);border-radius:2px}.components-panel input:is([type=url],[type=email],[type=number]):where(:disabled,.disabled)::placeholder{color:var(--wp-components-color-gray-600, #949494)}.components-panel .pwp-panel:not(.password,.integrations-fields){position:relative;margin-top:18px;padding-top:16px;border-top:1px solid rgba(196,196,196,.631372549)}.components-panel .pwp-panel:where(.rules,.segments,.profile-fields,.integrations-fields) .components-base-control,.components-panel .pwp-panel:where(.rules,.segments,.profile-fields,.integrations-fields) .components-base-control__field{margin-bottom:0;width:100%}.components-panel .pwp-panel:where(.rules,.segments,.profile-fields,.integrations-fields) .components-button{padding:0;height:30px;min-width:min-content}.components-panel .pwp-panel:where(.rules,.segments,.integrations-fields) .select-rule+.select-rule,.components-panel .pwp-panel:where(.rules,.segments,.integrations-fields) .select-integrations-plan+.select-integrations-plan{margin-top:.5em}.components-panel .pwp-panel:where(.rules,.segments,.integrations-fields) .help{margin-block:0}.components-panel .pwp-panel.profile-fields .profile-field{display:grid;gap:8px}.components-panel .pwp-panel.profile-fields .profile-field+.profile-field{margin-top:16px}.components-panel .pwp-panel.action{margin-bottom:2px}.components-panel .pwp-panel.action::before{content:"THEN";display:block;position:absolute;top:-0.6rem;left:calc(50% - (2ch + 1em));padding-inline:1em;background-color:#fff;font-size:.9rem;font-weight:bold}.components-panel .pwp-panel .rule-set__add-rule{margin-top:12px}.components-panel .pwp-panel :where(.bi,.dashicons,button svg){width:24px;height:24px;aspect-ratio:1;cursor:pointer}.components-panel .pwp-panel button:disabled :where(.bi,.dashicons,svg){cursor:default}.components-panel .pwp-panel .score-error{margin-inline:-15px}.components-panel .pwp-panel .score-error>*{margin-inline:0;margin-block-end:1em}.components-panel .pwp-panel .pwp-toggle label{flex:initial;cursor:pointer}.components-panel .pwp-panel .search-option-selected{display:grid;grid-template-columns:repeat(2, 1fr);gap:5px}.components-panel .pwp-panel .search-option-selected .search-option-selected-item{padding:8px;background:#f9f9f9}.components-panel .pwp-panel .components-search-control .components-input-control__container{background-color:#fff;border:1px solid var(--wp-components-color-gray-600, #949494)}.components-panel .pwp-panel .components-disabled .components-search-control .components-input-control__container{background-color:var(--wp-components-color-gray-100, #f0f0f0);border:none}.block-editor-format-toolbar__personalizewp-popover .components-popover__content{padding:1rem;width:auto}
  • personalizewp/tags/3.4.1/includes/class-api.php

    r3382403 r3458877  
    553553     * @param string $url  URL to sanitise to match browser origin format
    554554     *
    555      * @return string Sanitised URL
     555     * @return string Sanitised URL or empty
    556556     */
    557557    public function sanitize_origin_url( $url ) {
    558558
    559559        $_parts = wp_parse_url( $url );
    560         $url    = untrailingslashit( sprintf( '%s://%s', $_parts['scheme'], $_parts['host'] ) );
     560        if ( empty( $_parts['scheme'] ) || empty( $_parts['host'] ) ) {
     561            return '';
     562        }
     563        $url = untrailingslashit( sprintf( '%s://%s', $_parts['scheme'], $_parts['host'] ) );
    561564
    562565        return $url;
  • personalizewp/tags/3.4.1/includes/class-db-manager.php

    r3422812 r3458877  
    1212
    1313use PersonalizeWP\Traits\SingletonTrait;
     14use PersonalizeWP\Model\Contact;
     15use PersonalizeWP\Integrations\WooCommerce\WooCommerce_Memberships_Teams;
    1416
    1517defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
     
    3739     * @var int
    3840     */
    39     const DB_VERSION = 330; // Increment with each change in db
     41    const DB_VERSION = 341; // Increment with each change in db
    4042
    4143    /**
     
    6466        // Immediately check for possible database migrations, since already within `init` hook.
    6567        $this->check_migrate();
     68
     69        add_action( 'personalizewp_batch_user_memberships_team_backfill', array( $this, 'batch_user_memberships_team_backfill' ) );
    6670    }
    6771
     
    134138        if ( $current_db_version < 330 ) {
    135139            $this->upgrade_330( $current_db_version );
     140        }
     141
     142        if ( $current_db_version < 341 ) {
     143            $this->upgrade_341( $current_db_version );
    136144        }
    137145
     
    360368            $this->install_tables();
    361369        }
     370    }
     371
     372    /**
     373     * Executes changes made in 3.4.1.
     374     *
     375     * @since 3.4.1
     376     *
     377     * @param int $db_version The old (current) database version.
     378     *
     379     * @return void
     380     */
     381    private function upgrade_341( $db_version ) {
     382        global $wpdb;
     383
     384        if ( $db_version < 341 ) {
     385
     386            // Check for use of Teams, no need to run if not. Cannot check for our Teams class as this upgrade runs early.
     387            if ( ! class_exists( 'WC_Memberships_For_Teams_Loader' ) ) {
     388                return;
     389            }
     390            // Safety check for Action Scheduler, which is core within WooCommerce and needed for backfilling.
     391            if ( ! function_exists( 'as_enqueue_async_action' ) ) {
     392                return;
     393            }
     394
     395            // 1: Get all Visitor IDs with corresponding WP User ID meta, without a teams meta field ID
     396            $visitor_ids = $wpdb->get_col(
     397                $wpdb->prepare(
     398                    'SELECT meta1.contact_id
     399                    FROM %i as meta1
     400                    LEFT JOIN %i as meta2 ON ( meta1.contact_id = meta2.contact_id AND meta2.meta_key = %s )
     401                    WHERE meta1.meta_key = %s AND meta2.contact_id IS NULL',
     402                    $wpdb->prefix . 'pwp_contacts_meta',
     403                    $wpdb->prefix . 'pwp_contacts_meta',
     404                    'wc_memberships_team_id',
     405                    'wp_user_id'
     406                )
     407            );
     408
     409            $action_ids = array();
     410            // 2: Add new AS action for each found Visitor ID.
     411            foreach ( $visitor_ids as $visitor_id ) {
     412                $action_ids[] = as_enqueue_async_action(
     413                    'personalizewp_batch_user_memberships_team_backfill',
     414                    array( $visitor_id ),
     415                    'personalizewp_memberships_teams'
     416                );
     417            }
     418        }
     419    }
     420
     421    /**
     422     * Backfills a visitors Team ID for WooCommerce Memberships.
     423     *
     424     * @param int $visitor_id Visitor ID
     425     *
     426     * @return int|bool|WP_Error|void Returns early if the user doesn't exist, or the team is already set
     427     */
     428    public function batch_user_memberships_team_backfill( $visitor_id ) {
     429
     430        // Safety check
     431        $teams = WooCommerce_Memberships_Teams::instance();
     432        if ( empty( $teams ) ) {
     433            return new \WP_Error( 'personalizewp_teams_backfill_teams_not_available', __( 'Teams for WooCommerce Memberships not available', 'personalizewp' ) );
     434        }
     435
     436        // Check visitor ID validity.
     437        $visitor = Contact::get_instance( $visitor_id );
     438        if ( ! $visitor ) {
     439            return new \WP_Error( 'personalizewp_teams_backfill_invalid_visitor', __( 'Invalid Visitor ID', 'personalizewp' ) );
     440        }
     441
     442        // Double check for pre-existing memberships team.
     443        $_team_id = $visitor->get_metadata( 'wc_memberships_team_id', true );
     444        if ( ! empty( $_team_id ) ) {
     445            return;
     446        }
     447
     448        // Get WP User ID, *should* be valid.
     449        $wp_user_id = $visitor->get_metadata( 'wp_user_id', true );
     450        $team_id    = $teams->get_membership_team_id_by_user_id( $wp_user_id );
     451        if ( empty( $team_id ) ) {
     452            // No valid team, nothing to do.
     453            return;
     454        }
     455
     456        // Add/update new meta data
     457        return $visitor->update_metadata( 'wc_memberships_team_id', $team_id );
    362458    }
    363459
  • personalizewp/tags/3.4.1/includes/class-publicfacing.php

    r3422812 r3458877  
    107107         * @since 3.1.0
    108108         *
    109          * @param string[] $pwp_settings String indexed array of PersonalizeWP settings.
     109         * @param array[] $pwp_settings {
     110         *     String indexed array of PersonalizeWP settings for the core JS.
     111         *
     112         *     @type array ...$0 {
     113         *         An associative array of the variables.
     114         *
     115         *         @type string $root          URL root for all PersonalizeWP REST requests.
     116         *         @type string $nonceEndpoint URL endpoint for JS to retrieve a new nonce when visitor is logged in.
     117         *         @type bool   $isLoggedIn    Flag which triggers sending a 'X-WP-Nonce' header with REST calls to ensure no CSRF for users. Default false.
     118         *         @type bool   $delayInit     Flag to indicate the PersonalizeWP JavaScript should delay itself until some user interaction has occurred. Default false.
     119         *         @type string $apiToken      Token to restrict API responses to known domains, i.e. CSP authorisation.
     120         *     }
     121         * }
    110122         */
    111123        $pwp_settings = apply_filters(
    112124            'personalizewp_js_settings',
    113125            array(
    114                 'root'      => sanitize_url( get_rest_url() ), // phpcs:ignore WordPress.WP.DeprecatedFunctions.sanitize_url -- 5.9 un-deprecated this
    115                 'nonce'     => wp_create_nonce( 'wp_rest' ), // Required for checking on logged in status
    116                 'delayInit' => (bool) $this->plugin->get_setting( 'performance_delay_initialisation' ),
    117                 'apiToken'  => $this->plugin->api->get_api_auth_token( get_home_url() ),
     126                'root'          => sanitize_url( get_rest_url() ), // phpcs:ignore WordPress.WP.DeprecatedFunctions.sanitize_url -- 5.9 un-deprecated this
     127                'nonceEndpoint' => admin_url( 'admin-ajax.php?action=rest-nonce' ),
     128                'isLoggedIn'    => is_user_logged_in(),
     129                'delayInit'     => (bool) $this->plugin->get_setting( 'performance_delay_initialisation' ),
     130                'apiToken'      => $this->plugin->api->get_api_auth_token( get_home_url() ),
    118131            )
    119132        );
     
    193206        // We do this as the JS data will be part of the cached HTML.
    194207        $args = array(
    195             'trackAnon' => $this->plugin->should_track_anonymous_users(),
    196             'type'      => 'misc',
    197         );
    198         if ( is_user_logged_in() ) {
    199             // Frontend should not be cached and will be known.
    200             $args['userIsKnown'] = true;
    201         }
     208            'trackAnon'   => $this->plugin->should_track_anonymous_users(),
     209            'userIsKnown' => is_user_logged_in(), // Frontend should not be cached and will be known.
     210            'type'        => 'misc',
     211            'obj'         => null,
     212        );
    202213        if ( is_home() || is_front_page() ) {
    203214            $args['type'] = 'home';
     
    237248         * @since 3.3.0
    238249         *
    239          * @param array $args JS variables to pass to the PWP Tracking module
     250         * @param array[] $args {
     251         *     JS variables to pass to the PWP Tracking module.
     252         *
     253         *     @type array ...$0 {
     254         *         An associative array of the variables.
     255         *
     256         *         @type bool     $trackAnon   Flag to indicate to tracking JS if anonymous users should be tracked or not. Default false.
     257         *         @type bool     $userIsKnown Flag to indicate current visitor is known to the site. Default false.
     258         *         @type string   $type        Type of event being tracked.
     259         *         @type int|null $obj         Object ID of current CPT or Taxonomy, default to null.
     260         *     }
     261         * }
    240262         */
    241263        return apply_filters( 'personalizewp_get_tracking_variables', $args );
  • personalizewp/tags/3.4.1/includes/integrations/woocommerce/class-woocommerce-memberships-teams.php

    r3452048 r3458877  
    112112    public function is_profile_listing_screen(): bool {
    113113        $screen = get_current_screen();
    114         return is_object( $screen ) && 'admin_page_' . PageContacts::SLUG === $screen->id;
     114        return is_object( $screen ) && str_ends_with( $screen->id, PageContacts::SLUG );
    115115    }
    116116
     
    123123    public function is_recent_events_screen(): bool {
    124124        $screen = get_current_screen();
    125         return is_object( $screen ) && 'personalize_page_' . PageActivities::SLUG === $screen->id;
     125        return is_object( $screen ) && str_ends_with( $screen->id, PageActivities::SLUG );
    126126    }
    127127
     
    134134    public function is_team_profile_screen(): bool {
    135135        $screen          = get_current_screen();
    136         $is_profile_page = is_object( $screen ) && 'admin_page_' . PageContacts::SLUG === $screen->id;
     136        $is_profile_page = is_object( $screen ) && str_ends_with( $screen->id, PageContacts::SLUG );
    137137        $action          = isset( $_REQUEST[ Admin::URL_ACTION ] ) ? sanitize_text_field( wp_unslash( $_REQUEST[ Admin::URL_ACTION ] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: nonce verification not required
    138138        $is_team_profile = 'view-team' === $action;
  • personalizewp/tags/3.4.1/package.json

    r3452048 r3458877  
    22  "name": "personalizewp",
    33  "title": "PersonalizeWP",
    4   "version": "3.4.0",
     4  "version": "3.4.1",
    55  "description": "PersonalizeWP plugin",
    66  "author": "PersonalizeWP",
  • personalizewp/tags/3.4.1/personalizewp.php

    r3452048 r3458877  
    1111 * Plugin URI:        https://personalizewp.com/
    1212 * Description:       Add powerful personalization features to your WordPress site. Show different content to different visitors based on their behavior, profile, location, and more.
    13  * Version:           3.4.0
     13 * Version:           3.4.1
    1414 * Author:            Filter
    1515 * Author URI:        https://filter.agency/
     
    4040 * Current plugin version.
    4141 */
    42 define( 'PERSONALIZEWP_VERSION', '3.4.0' );
     42define( 'PERSONALIZEWP_VERSION', '3.4.1' );
    4343
    4444// Load autoloader.
  • personalizewp/tags/3.4.1/public/css/pwp.css

    r3452048 r3458877  
    11@charset "UTF-8";
    2 /*! PersonalizeWP v3.4.0 | (c) 2026 PersonalizeWP | GPL-3.0 License */
     2/*! PersonalizeWP v3.4.1 | (c) 2026 PersonalizeWP | GPL-3.0 License */
    33:where(pwp-block, wp-dxp):empty,
    44:where(pwp-block, wp-dxp):not(:defined) {
  • personalizewp/tags/3.4.1/public/css/pwp.min.css

    r3452048 r3458877  
    11@charset "UTF-8";
    2 /*! PersonalizeWP v3.4.0 | (c) 2026 PersonalizeWP | GPL-3.0 License */
     2/*! PersonalizeWP v3.4.1 | (c) 2026 PersonalizeWP | GPL-3.0 License */
    33:where(pwp-block,wp-dxp):empty,:where(pwp-block,wp-dxp):not(:defined){display:none !important}:where(pwp-content-variations):where(:defined:not([hidden]),:not(:defined)){display:block}:where(pwp-block-pwd):not(:defined){display:none}:where(pwp-block-pwd):defined{display:block}:where(.personalizewp-password-form) :where(.personalizewp-password-form-input input){display:block;font:inherit;padding:calc(.332em + 2px) calc(.667em + 2px);border:1px solid silver;border-radius:.225rem}:where(.personalizewp-password-form) :where([aria-invalid=true]){outline:2px solid red}:where(.personalizewp-password-form) :where([aria-invalid=true])~:where(.invalid-feedback){display:block;visibility:visible}
  • personalizewp/tags/3.4.1/public/js/pwp.asset.php

    r3452048 r3458877  
    1 <?php return array('dependencies' => array('wp-hooks'), 'version' => 'ed34d7f38f5bb44053fc');
     1<?php return array('dependencies' => array('wp-hooks'), 'version' => 'f39dfd52965eae76aa5b');
  • personalizewp/tags/3.4.1/public/js/pwp.js

    r3452048 r3458877  
    1 (()=>{"use strict";const e=window.wp.hooks;window.PersonalizeWP=function(t,n){let o={pwpGet:(e,t=!1,n="personalizewp")=>{const o=localStorage.getItem(`${n}_${e}`);return o?t?JSON.parse(o):o:null},pwpStore:(e,t,n="personalizewp")=>{localStorage.setItem(`${n}_${e}`,JSON.stringify(t))},pwpClear:(e,t="personalizewp")=>{localStorage.removeItem(`${t}_${e}`)},callApi:async(e,t)=>{try{const n=await fetch(`${a}${e}`,{mode:"cors",method:"POST",cache:"no-cache",headers:{Accept:"application/json, */*;q=0.1","Cache-Control":"no-cache","Content-type":"application/json","X-Requested-With":"XMLHttpRequest",...window.pwpSettings&&window.pwpSettings.apiToken&&{"X-PWP-Auth-Token":window.pwpSettings.apiToken},...window.pwpSettings&&window.pwpSettings.nonce&&{"X-WP-Nonce":window.pwpSettings.nonce}},body:JSON.stringify(t)});if(!n.ok)throw new Error(`Response status: ${n.status}`);return await n.json()}catch(e){console.warn("API Error:",e)}return null},nodeScriptReplace:e=>{if("SCRIPT"===e.tagName)e.parentNode.replaceChild(o.nodeScriptClone(e),e);else for(var t=-1,n=e.childNodes;++t<n.length;)o.nodeScriptReplace(n[t]);return e},nodeScriptClone:e=>{var t=document.createElement("script");t.text=e.innerHTML;for(var n,o=-1,i=e.attributes;++o<i.length;)t.setAttribute((n=i[o]).name,n.value);return t}};function i(e,t){return e=parseInt(e),t=parseInt(t),isNaN(e)||isNaN(t)?0:(t>e&&(t=Math.round(t/1e3)),Math.round((e-t)/86400))}const s=[],a=(window.pwpSettings?window.pwpSettings.root:"/wp-json/")+"personalizewp/",r=[];let c=!1;const d=Math.round(Date.now()/1e3),l=(new Date).toTimeString(),p={timeOfDay:function(){const e=(new Date).getHours();return e>=0&&e<6?"nighttime":e>=6&&e<12?"morning":e>=12&&e<18?"afternoon":e>=18&&e<=23?"evening":""}(),currentTime:l.substring(0,l.indexOf(" ")),currentTimestamp:(new Date).toISOString(),isReturningVisitor:!0,daysSinceLastVisit:0,deviceType:function(){const e=function(){const e=navigator.userAgent||navigator.vendor||window.opera;return/windows phone/i.test(e)?"windows":/android/i.test(e)?"android":/iPad|iPhone|iPod/.test(e)&&!window.MSStream?"ios":/mac/i.test(e)?"macos":/win/i.test(e)?"windows":/linux/i.test(e)?"linux":""}();return function(){let e=!1;var t;return t=navigator.userAgent||navigator.vendor||window.opera,(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(t)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(t.substr(0,4)))&&(e=!0),e}()?["mobile",e]:function(){const e=navigator.userAgent.toLowerCase();return/(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/.test(e)}()?["tablet",e]:["desktop",e]}(),uid:null!==(n=o.pwpGet("tracked_user",!0,"pwp")?.id)&&void 0!==n?n:""},u=o.pwpGet("first_visit");null===u?(o.pwpStore("first_visit",d),p.isReturningVisitor=!1):u>d?o.pwpStore("first_visit",Math.round(u/1e3)):1>i(d,parseInt(u))&&(p.isReturningVisitor=!1);var w,m=sessionStorage.getItem("personalizewp_last_session");async function g(e,t="v2/blocks"){if(0===e.length)return null;const n={...p,location:location.pathname,blocks:e,urlQueryString:window.location.search+window.location.hash,referrerURL:document.referrer,pageProps:h(window?.PWPTrack||{})},i=await o.callApi(t,n);return i&&i.length?i:null}function h(e){const t=["type","obj"];return Object.keys(e).filter(e=>t.includes(e)).reduce((t,n)=>({...t,[n]:e[n]}),{})}function b(e,t){s.indexOf(t)>=0||(e(),s.push(t))}function f(e,t){window.pwpSettings.delayInit?function(e,t){const n=()=>{b(e,t)},o={once:!0};document.body.addEventListener("mousemove",n,o),document.body.addEventListener("scroll",n,o),document.body.addEventListener("keydown",n,o),document.body.addEventListener("click",n,o),document.body.addEventListener("touchstart",n,o)}(e,t):"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{b(e,t)},{once:!0}):b(e,t)}null===m||isNaN(parseInt(m))?(m=parseInt(null!==(w=o.pwpGet("last_visit"))&&void 0!==w?w:d),sessionStorage.setItem("personalizewp_last_session",m)):parseInt(m)>d&&(m=Math.round(parseInt(m)/1e3),sessionStorage.setItem("personalizewp_last_session",m)),p.daysSinceLastVisit=i(d,m),o.pwpStore("last_visit",d);const v=[];class k extends HTMLElement{connectedCallback(){this.blockId&&(void 0===v[this.delayed]&&(v[this.delayed]={parsing:!1,elements:[]}),v[this.delayed].elements.push(this))}get blockId(){return this.getAttribute("block-id")}get delayed(){let e=this.getAttribute("delayed");return e?Number(e):0}get lifetime(){let e=this.getAttribute("lifetime");return e?Number(e):0}}return window.customElements.define("pwp-block",k),f(function e(){Object.keys(v).forEach(function(t){if(v[t].parsing)return;v[t].parsing=!0;const n=v[t].elements;let i=[];for(let e of n)i.push(e.blockId);i.length?g(i).then(i=>{if(!Array.isArray(i))throw"No blocks to parse";const s=[];i.forEach(function(e){const t=n.shift();e?s.push([t,e]):t.remove()}),s.length&&setTimeout(function(){s.forEach(function(e){const t=e[0].parentNode;let n=document.createElement("div");if(n.innerHTML=e[1],n=o.nodeScriptReplace(n),e[0].lifetime){const t=1e3*e[0].lifetime,o=n.childNodes;for(const e of o)setTimeout(function(){e.remove()},t)}e[0].replaceWith(...n.childNodes);const i=new CustomEvent("PWP:parsePlaceholder",{bubbles:!0,cancelable:!0,detail:{container:t}});t.dispatchEvent(i)}),document.dispatchEvent(new CustomEvent("DOMContentLoaded"));const t=new CustomEvent("PWP:parsedPlaceholders",{bubbles:!0,cancelable:!0});document.dispatchEvent(t),e()},1e3*t),v[t].parsing=!1}).catch(e=>{console.log(e)}):v[t].parsing=!1})},"pwp"),document.addEventListener("DOMContentLoaded",()=>function(){c=!0;for(let e of r)e.ready(this)}(),{once:!0}),t.utils=o,t.getBlocks=g,t.module=function(e,t,n=!1){const o=()=>{t.init&&t.init(),t.ready&&(c?t.ready(this):r.push(t))};n?o():f(o,e)},t.hooks=(0,e.createHooks)(),t}({})})();
     1(()=>{"use strict";const e=window.wp.hooks;window.PersonalizeWP=function(t,n){function o(e){if(!e)return;const t=Math.round(Date.now()/1e3);i.pwpStore("nonce",{nonce:e,timestamp:t})}let i={pwpGet:(e,t=!1,n="personalizewp")=>{const o=localStorage.getItem(`${n}_${e}`);return o?t?JSON.parse(o):o:null},pwpStore:(e,t,n="personalizewp")=>{localStorage.setItem(`${n}_${e}`,JSON.stringify(t))},pwpClear:(e,t="personalizewp")=>{localStorage.removeItem(`${t}_${e}`)},callApi:async(e,t,n=!0)=>{try{const a=await async function(){if(!window.pwpSettings?.isLoggedIn)return null;let{nonce:e,timestamp:t}=function(){const e=i.pwpGet("nonce",!0)||null;return e||i.pwpClear("nonce"),{nonce:e&&e?.nonce||"",timestamp:e&&e?.timestamp||0}}();const n=Math.round(Date.now()/1e3);if(!e||!t||t<n-43200){if(e=await async function(){if(!window.pwpSettings?.nonceEndpoint)return null;try{const e=await fetch(window.pwpSettings?.nonceEndpoint,{mode:"cors",cache:"no-cache",headers:{"Cache-Control":"no-cache","X-Requested-With":"XMLHttpRequest"}});if(!e.ok)throw new Error(`Response status: ${e.status}`);return await e.text()}catch(e){return console.warn("PersonalizeWP: Nonce Error:",e),null}}(),!e)return null;o(e)}return await e}(),s=await fetch(`${r}${e}`,{mode:"cors",method:"POST",cache:"no-cache",headers:{Accept:"application/json, */*;q=0.1","Cache-Control":"no-cache","Content-type":"application/json","X-Requested-With":"XMLHttpRequest",...window.pwpSettings?.apiToken&&{"X-PWP-Auth-Token":window.pwpSettings.apiToken},...a&&{"X-WP-Nonce":a}},body:JSON.stringify(t)});if(!s.ok){if(403===s.status&&a&&n)return i.pwpClear("nonce"),await i.callApi(e,t,!1);throw new Error(`Response status: ${s.status}`)}const c=s.headers.get("X-WP-Nonce");return a!==c&&o(c),await s.json()}catch(e){console.warn("PersonalizeWP: API Error:",e)}return null},nodeScriptReplace:e=>{if("SCRIPT"===e.tagName)e.parentNode.replaceChild(i.nodeScriptClone(e),e);else for(var t=-1,n=e.childNodes;++t<n.length;)i.nodeScriptReplace(n[t]);return e},nodeScriptClone:e=>{var t=document.createElement("script");t.text=e.innerHTML;for(var n,o=-1,i=e.attributes;++o<i.length;)t.setAttribute((n=i[o]).name,n.value);return t}};function a(e,t){return e=parseInt(e),t=parseInt(t),isNaN(e)||isNaN(t)?0:(t>e&&(t=Math.round(t/1e3)),Math.round((e-t)/86400))}const s=[],r=(window.pwpSettings?window.pwpSettings.root:"/wp-json/")+"personalizewp/",c=[];let l=!1;const d=Math.round(Date.now()/1e3),p=(new Date).toTimeString(),u={timeOfDay:function(){const e=(new Date).getHours();return e>=0&&e<6?"nighttime":e>=6&&e<12?"morning":e>=12&&e<18?"afternoon":e>=18&&e<=23?"evening":""}(),currentTime:p.substring(0,p.indexOf(" ")),currentTimestamp:(new Date).toISOString(),isReturningVisitor:!0,daysSinceLastVisit:0,deviceType:function(){const e=function(){const e=navigator.userAgent||navigator.vendor||window.opera;return/windows phone/i.test(e)?"windows":/android/i.test(e)?"android":/iPad|iPhone|iPod/.test(e)&&!window.MSStream?"ios":/mac/i.test(e)?"macos":/win/i.test(e)?"windows":/linux/i.test(e)?"linux":""}();return function(){let e=!1;var t;return t=navigator.userAgent||navigator.vendor||window.opera,(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(t)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(t.substr(0,4)))&&(e=!0),e}()?["mobile",e]:function(){const e=navigator.userAgent.toLowerCase();return/(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/.test(e)}()?["tablet",e]:["desktop",e]}(),uid:null!==(n=i.pwpGet("tracked_user",!0,"pwp")?.id)&&void 0!==n?n:""},w=i.pwpGet("first_visit");null===w?(i.pwpStore("first_visit",d),u.isReturningVisitor=!1):w>d?i.pwpStore("first_visit",Math.round(w/1e3)):1>a(d,parseInt(w))&&(u.isReturningVisitor=!1);var m,h=sessionStorage.getItem("personalizewp_last_session");async function g(e,t="v2/blocks"){if(0===e.length)return null;const n={...u,location:location.pathname,blocks:e,urlQueryString:window.location.search+window.location.hash,referrerURL:document.referrer,pageProps:f(window?.PWPTrack||{})},o=await i.callApi(t,n);return o&&o.length?o:null}function f(e){const t=["type","obj"];return Object.keys(e).filter(e=>t.includes(e)).reduce((t,n)=>({...t,[n]:e[n]}),{})}function b(e,t){s.indexOf(t)>=0||(e(),s.push(t))}function v(e,t){window.pwpSettings.delayInit?function(e,t){const n=()=>{b(e,t)},o={once:!0};document.body.addEventListener("mousemove",n,o),document.body.addEventListener("scroll",n,o),document.body.addEventListener("keydown",n,o),document.body.addEventListener("click",n,o),document.body.addEventListener("touchstart",n,o)}(e,t):"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{b(e,t)},{once:!0}):b(e,t)}null===h||isNaN(parseInt(h))?(h=parseInt(null!==(m=i.pwpGet("last_visit"))&&void 0!==m?m:d),sessionStorage.setItem("personalizewp_last_session",h)):parseInt(h)>d&&(h=Math.round(parseInt(h)/1e3),sessionStorage.setItem("personalizewp_last_session",h)),u.daysSinceLastVisit=a(d,h),i.pwpStore("last_visit",d);const k=[];class y extends HTMLElement{connectedCallback(){this.blockId&&(void 0===k[this.delayed]&&(k[this.delayed]={parsing:!1,elements:[]}),k[this.delayed].elements.push(this))}get blockId(){return this.getAttribute("block-id")}get delayed(){let e=this.getAttribute("delayed");return e?Number(e):0}get lifetime(){let e=this.getAttribute("lifetime");return e?Number(e):0}}return window.customElements.define("pwp-block",y),v(function e(){Object.keys(k).forEach(function(t){if(k[t].parsing)return;k[t].parsing=!0;const n=k[t].elements;let o=[];for(let e of n)o.push(e.blockId);o.length?g(o).then(o=>{if(!Array.isArray(o))throw"No blocks to parse";const a=[];o.forEach(function(e){const t=n.shift();e?a.push([t,e]):t.remove()}),a.length&&setTimeout(function(){a.forEach(function(e){const t=e[0].parentNode;let n=document.createElement("div");if(n.innerHTML=e[1],n=i.nodeScriptReplace(n),e[0].lifetime){const t=1e3*e[0].lifetime,o=n.childNodes;for(const e of o)setTimeout(function(){e.remove()},t)}e[0].replaceWith(...n.childNodes);const o=new CustomEvent("PWP:parsePlaceholder",{bubbles:!0,cancelable:!0,detail:{container:t}});t.dispatchEvent(o)}),document.dispatchEvent(new CustomEvent("DOMContentLoaded"));const t=new CustomEvent("PWP:parsedPlaceholders",{bubbles:!0,cancelable:!0});document.dispatchEvent(t),e()},1e3*t),k[t].parsing=!1}).catch(e=>{console.log(e)}):k[t].parsing=!1})},"pwp"),document.addEventListener("DOMContentLoaded",()=>function(){l=!0;for(let e of c)e.ready(this)}(),{once:!0}),t.utils=i,t.getBlocks=g,t.module=function(e,t,n=!1){const o=()=>{t.init&&t.init(),t.ready&&(l?t.ready(this):c.push(t))};n?o():v(o,e)},t.hooks=(0,e.createHooks)(),t}({})})();
  • personalizewp/tags/3.4.1/src/public/js/pwp.js

    r3452048 r3458877  
    44window.PersonalizeWP = (function (exports) {
    55    "use strict";
     6
     7    /**
     8     * Returns the local storage of the users nonce and its TTL.
     9     * @returns {object}
     10     */
     11    function getStoredUserNonce() {
     12        const userNonce = utils.pwpGet('nonce', true) || null;
     13        if ( ! userNonce ) {
     14            // Clear in case of bad data.
     15            utils.pwpClear('nonce');
     16        }
     17        // Validate stored nonce, revert to defaults otherwise
     18        const data = {
     19            nonce: (userNonce && userNonce?.nonce ) || '',
     20            timestamp: (userNonce && userNonce?.timestamp) || 0,
     21        };
     22        return data;
     23    }
     24
     25    /**
     26     * Store an updated nonce, refreshing its TTL to now.
     27     * @param {string} nonce
     28     */
     29    function storeUserNonce( nonce ) {
     30        if ( ! nonce ) return;
     31        const now = Math.round(Date.now() / 1000); // Now in seconds
     32
     33        // Store the updated nonce.
     34        utils.pwpStore( 'nonce', { nonce, timestamp: now } );
     35    }
     36
     37    /**
     38     * Returns a new CSRF nonce for the current user.
     39     * @returns {string | null}
     40     */
     41    async function refreshUserNonce() {
     42        // Without an endpoint, can never get a user nonce.
     43        if (! window.pwpSettings?.nonceEndpoint) {
     44            return null;
     45        }
     46        try {
     47            const response = await fetch(window.pwpSettings?.nonceEndpoint, {
     48                mode:  'cors', // Assume cross-origin
     49                cache: 'no-cache',
     50                headers: {
     51                    'Cache-Control': 'no-cache',
     52                    'X-Requested-With': 'XMLHttpRequest',
     53                }
     54            });
     55            if (!response.ok) {
     56                throw new Error(`Response status: ${response.status}`);
     57            }
     58            // New nonce generated.
     59            return await response.text();
     60        } catch( error ) {
     61            console.warn('PersonalizeWP: Nonce Error:', error);
     62            return null;
     63        }
     64        return null;
     65    }
     66
     67    /**
     68     * Checks for a stored user nonce, refreshes if needed, before returning.
     69     * @returns {string | null}
     70     */
     71    async function getUserNonce() {
     72        if ( ! window.pwpSettings?.isLoggedIn ) {
     73            return null;
     74        }
     75        // Get the stored nonce
     76        let { nonce, timestamp } = getStoredUserNonce();
     77        const now = Math.round(Date.now() / 1000); // Now in seconds
     78        // TTL for nonce is 12 hrs.
     79        if ( ! nonce || ! timestamp || timestamp < ( now - ( 60 * 60 * 12 ) ) ) {
     80            // Refresh the nonce and its TTL
     81            nonce = await refreshUserNonce(); // MUST wait for the nonce to resolve.
     82            if ( ! nonce ) {
     83                // Console already warned in refreshUserNonce()
     84                return null;
     85            }
     86            // Store the updated nonce.
     87            storeUserNonce( nonce );
     88        }
     89        return await nonce;
     90    }
    691
    792    /**
     
    44129
    45130        /**
    46          * Call a PWP request api
    47          * @param {String} u The url of the endpoint
    48          * @param {String} b The parameter body
     131         * Make a PersonalizeWP API request
     132         * @param {String} url The url of the endpoint
     133         * @param {String} body The parameter body
     134         * @param {Boolean} retry Should the request retry after the first failure. Default true when using nonces
    49135         * @return {Promise<any | null>} The response body of request
    50136         */
    51         callApi: async (u, b) => {
     137        callApi: async (url, body, retry = true) => {
    52138            try {
    53                 // const loc = document.location;
    54                 const response = await fetch(`${baseUrl}${u}`, {
     139                const userNonce = await getUserNonce(); // MUST wait for the nonce to complete.
     140                const response = await fetch(`${baseUrl}${url}`, {
    55141                    mode:  'cors', // Assume cross-origin
    56142                    method: 'POST', // Generally not 'creating' content, but POST allows a larger quantity of params via the body
     
    61147                        'Content-type': 'application/json',
    62148                        'X-Requested-With': 'XMLHttpRequest',
    63                         ...(window.pwpSettings &&
    64                             // Safely check for auth token
    65                             window.pwpSettings.apiToken && {
     149                        // Safely check and include auth token
     150                        ...(window.pwpSettings?.apiToken && {
    66151                                'X-PWP-Auth-Token': window.pwpSettings.apiToken,
    67152                            }),
    68                         ...(window.pwpSettings &&
    69                             // Safely check for nonce
    70                             window.pwpSettings.nonce && {
    71                                 'X-WP-Nonce': window.pwpSettings.nonce,
    72                             }),
     153                        // Safely check and include a logged in user nonce
     154                        ...(userNonce && {
     155                            'X-WP-Nonce': userNonce
     156                        }),
    73157                    },
    74                     body: JSON.stringify(b),
     158                    body: JSON.stringify(body),
    75159                });
    76160                if (!response.ok) {
     161                    if ( 403 === response.status && userNonce && retry ) {
     162                        // Possible corruption of the existing nonce, clear storage and try again.
     163                        utils.pwpClear('nonce');
     164
     165                        // Ensure we only try one more time. No infinite loops.
     166                        return await utils.callApi( url, body, false );
     167                    }
    77168                    throw new Error(`Response status: ${response.status}`);
     169                }
     170                // Update the users nonce when a new nonce is returned with the response.
     171                const returnedNonce = response.headers.get('X-WP-Nonce');
     172                if ( userNonce !== returnedNonce ) {
     173                    storeUserNonce( returnedNonce );
    78174                }
    79175                return await response.json();
    80176            } catch (error) {
    81                 console.warn('API Error:', error);
     177                console.warn('PersonalizeWP: API Error:', error);
    82178            }
    83179            return null;
  • personalizewp/trunk/README.txt

    r3452048 r3458877  
    44Requires at least: 6.2.0
    55Tested up to: 6.9
    6 Stable tag: 3.4.0
     6Stable tag: 3.4.1
    77Requires PHP: 7.4
    88License: GPL v3
     
    181181
    182182== Changelog ==
     183
     184= 3.4.1 =
     185
     186* Enhancement: Remove fixed authorisation nonces from use in JS, fixing potential 403 errors for heavily cached websites.
     187* Added: Back fill Teams for WooCommerce Memberships on all known visitors when upgrading.
     188* Bug fix: Undefined array keys 'scheme' and 'host' @props Paul Wong-Gibbs.
     189* Bug fix: Change export requests from showing a download link when underlying file has already been deleted.
     190* Bug fix: Fix translation issue causing pagination screen options to disappear on some admin screens.
     191* Bug fix: Fix issue causing Membership Teams columns and filters to disappear when not using US English language.
    183192
    184193= 3.4.0 =
  • personalizewp/trunk/admin/class-data-export.php

    r3452048 r3458877  
    709709
    710710        // Only fully processed export requests have filenames.
    711         $filename = get_post_meta( $post_id, self::META_EXPORT_FILE, true );
     711        $filename = get_post_meta( $post_id, self::META_EXPORT_FILE, true );
    712712        if ( ! empty( $filename ) ) {
    713713            $export_dir = $this->get_export_directory();
     
    784784     */
    785785    public function cleanup_old_export_files(): void {
     786
    786787        $export_dir = $this->get_export_directory();
    787788        if ( ! $export_dir ) {
     
    789790        }
    790791
    791         $cutoff_date = strtotime( '-7 days' );
    792         $files       = glob( $export_dir . '/*.csv' );
    793 
    794         foreach ( $files as $file ) {
    795             if ( filemtime( $file ) < $cutoff_date ) {
    796                 wp_delete_file( $file );
    797             }
     792        // Get requests that are older than 7 days.
     793        $query_args = array(
     794            'post_type'      => self::POST_TYPE,
     795            'posts_per_page' => -1, // Need to get all
     796            'orderby'        => 'date',
     797            'order'          => 'DESC',
     798            'date_query'     => array(
     799                'before' => '-7 days',
     800            ),
     801            'meta_query'     => array(
     802                'has_file' => array(
     803                    'key'     => self::META_EXPORT_FILE,
     804                    'compare' => 'EXISTS',
     805                ),
     806            ),
     807        );
     808
     809        $query    = new \WP_Query();
     810        $requests = $query->query( $query_args );
     811
     812        foreach ( $requests as $export_request ) {
     813            // Doesn't matter what the status of the request is,
     814            // only that there is an export filename available.
     815            $filename = get_post_meta( $export_request->ID, self::META_EXPORT_FILE, true );
     816            if ( ! empty( $filename ) ) {
     817                $file_path = $export_dir . '/' . $filename;
     818
     819                if ( file_exists( $file_path ) ) {
     820                    wp_delete_file( $file_path );
     821                }
     822            }
     823
     824            // Always clear the export filename.
     825            delete_post_meta( $export_request->ID, self::META_EXPORT_FILE );
    798826        }
    799827    }
  • personalizewp/trunk/admin/class-pageactivities.php

    r3452048 r3458877  
    7777        $screen = get_current_screen();
    7878
    79         $is_screen = is_object( $screen ) && 'personalize_page_' . self::SLUG === $screen->id;
     79        $is_screen = is_object( $screen ) && str_ends_with( $screen->id, self::SLUG );
    8080        if ( ! $is_screen ) {
    8181            return;
  • personalizewp/trunk/admin/class-pagecategories.php

    r3452048 r3458877  
    109109        $screen = get_current_screen();
    110110
    111         $is_screen = is_object( $screen ) && 'admin_page_' . self::SLUG === $screen->id;
     111        $is_screen = is_object( $screen ) && str_ends_with( $screen->id, self::SLUG );
    112112        if ( ! $is_screen ) {
    113113            return;
  • personalizewp/trunk/admin/class-pagecontacts.php

    r3452048 r3458877  
    9999        $screen = get_current_screen();
    100100
    101         $is_screen = is_object( $screen ) && 'admin_page_' . self::SLUG === $screen->id;
     101        $is_screen = is_object( $screen ) && str_ends_with( $screen->id, self::SLUG );
    102102        if ( ! $is_screen ) {
    103103            return;
  • personalizewp/trunk/admin/class-pagedataexport.php

    r3452048 r3458877  
    8888        $screen = get_current_screen();
    8989
    90         $is_screen = is_object( $screen ) && 'admin_page_' . self::SLUG === $screen->id;
     90        $is_screen = is_object( $screen ) && str_ends_with( $screen->id, self::SLUG );
    9191        if ( ! $is_screen ) {
    9292            return;
  • personalizewp/trunk/admin/class-pagerules.php

    r3452048 r3458877  
    9999        $screen = get_current_screen();
    100100
    101         $is_screen = is_object( $screen ) && 'personalize_page_' . self::SLUG === $screen->id;
     101        $is_screen = is_object( $screen ) && str_ends_with( $screen->id, self::SLUG );
    102102        if ( ! $is_screen ) {
    103103            return;
  • personalizewp/trunk/admin/class-pagescoringrules.php

    r3452048 r3458877  
    122122        $screen = get_current_screen();
    123123
    124         $is_screen = is_object( $screen ) && 'personalize_page_' . self::SLUG === $screen->id;
     124        $is_screen = is_object( $screen ) && str_ends_with( $screen->id, self::SLUG );
    125125        if ( ! $is_screen ) {
    126126            return;
  • personalizewp/trunk/admin/class-pagesegments.php

    r3452048 r3458877  
    113113        $screen = get_current_screen();
    114114
    115         $is_screen = is_object( $screen ) && 'personalize_page_' . self::SLUG === $screen->id;
     115        $is_screen = is_object( $screen ) && str_ends_with( $screen->id, self::SLUG );
    116116        if ( ! $is_screen ) {
    117117            return;
  • personalizewp/trunk/admin/css/admin.css

    r3452048 r3458877  
    11@charset "UTF-8";
    2 /*! PersonalizeWP v3.4.0 | (c) 2026 PersonalizeWP | GPL-3.0 License */
     2/*! PersonalizeWP v3.4.1 | (c) 2026 PersonalizeWP | GPL-3.0 License */
    33body.pwp-page.pwp-fixed {
    44    position: fixed;
  • personalizewp/trunk/admin/css/admin.min.css

    r3452048 r3458877  
    11@charset "UTF-8";
    2 /*! PersonalizeWP v3.4.0 | (c) 2026 PersonalizeWP | GPL-3.0 License */
     2/*! PersonalizeWP v3.4.1 | (c) 2026 PersonalizeWP | GPL-3.0 License */
    33body.pwp-page.pwp-fixed{position:fixed;min-width:100vw}body.pwp-page #wpcontent{padding-left:0 !important}body.pwp-page #screen-meta{margin-left:20px}body.pwp-page #screen-meta-links{margin-bottom:min(-40px,-3rem)}:where(#personalizewp){--color-dark: #1A1A1A;--color-light: #FCFCFF;--color-mid: #555;--color-mid-glare: #c4c4c4;--color-primary: #e1236c;--color-primary-shade: #8c003a;--color-primary-glare: #ffd9e0;--color-secondary: #002F5F;--color-secondary-shade: #001134;--color-secondary-glare: #d8e6f8;--required: #dc3545;accent-color:var(--color-primary);--color-text: #3c434a;--color-text-glare: #999;--color-text-link: var(--color-secondary);--color-text-link-hover: var(--color-primary);--color-nav-tab: var(--color-mid);--color-nav-tab-hover: var(--color-dark);--color-nav-tab-border: var(--color-secondary);--color-focus-ring: var(--color-primary);--color-warning-border: #d63638;--color-warning-background: var(--color-light);--color-success-border: #42BE65;--color-success-background: #DEFBE6;--color-info-border: var(--color-secondary);--color-info-background: #F5FAFF}:where(#personalizewp) *{box-sizing:border-box}:where(#personalizewp) svg{vertical-align:baseline}:where(#personalizewp) :is(h2,h3,h4,h5){margin-block-start:0;margin-block-end:.5rem;font-weight:500;line-height:1.2}:where(#personalizewp) h2{font-size:2rem}:where(#personalizewp) h3{font-size:1.75rem}:where(#personalizewp) h4{font-size:1.5rem}:where(#personalizewp) h5{font-size:1.25rem}:where(#personalizewp) p{margin-block:0}:where(#personalizewp) a{text-decoration:none;color:var(--color-text-link)}:where(#personalizewp) a:is(:hover,:focus-within){text-decoration:underline;color:var(--color-text-link-hover)}:where(#personalizewp) table{align-self:flex-start;flex-grow:1;flex-basis:0}:where(#personalizewp) table :where(th){font-weight:bold;text-align:inherit}:where(#personalizewp) table :where(th):not(.check-column,.column-cb){padding-inline-end:min(5vw,2rem);min-width:12ch}:where(#personalizewp) table :where(td):not(.check-column,.column-cb){min-width:15ch;word-break:break-all}:is(#personalizewp){clear:both;display:flex;flex-direction:column;background:var(--color-light);min-height:100vh;line-height:1.5;font-size:1rem;padding-inline:20px;padding-block-end:1em}:is(#personalizewp) a:where(.back){display:inline-flex;align-items:center;gap:4px}:is(#personalizewp) [hidden]{display:none !important}:is(#personalizewp) .row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}:is(#personalizewp) .col-12{position:relative;width:100%;padding-right:15px;padding-left:15px}@media(min-width: 992px){:is(#personalizewp) .col-lg-6{flex:0 0 50%;max-width:50%}}@media(min-width: 1200px){:is(#personalizewp) .col-xl-10{flex:0 0 83.33333333%;max-width:83.33333333%}}:is(#personalizewp) .mb-2{margin-bottom:.5rem !important}:is(#personalizewp) .mb-3{margin-bottom:1rem !important}:is(#personalizewp) .mb-4{margin-bottom:1.5rem !important}@media(min-width: 576px){:is(#personalizewp) .mb-sm-3{margin-bottom:1rem !important}}:is(#personalizewp) .with-sidebar{display:flex;flex-wrap:wrap;gap:var(--gutter, var(--gap-width, 1rem))}:is(#personalizewp) .with-sidebar:not([data-direction])>:first-child{flex-basis:var(--sidebar-target-width, 25rem);flex-grow:1}:is(#personalizewp) .with-sidebar:not([data-direction])>:last-child{flex-basis:0;flex-grow:999;min-inline-size:var(--sidebar-content-min-width, 50%)}:is(#personalizewp) .with-sidebar[data-direction=rtl]>:last-child{flex-basis:var(--sidebar-target-width, 25rem);flex-grow:1}:is(#personalizewp) .with-sidebar[data-direction=rtl]>:first-child{flex-basis:0;flex-grow:999;min-inline-size:var(--sidebar-content-min-width, 50%)}:is(#personalizewp) .cluster{display:flex;flex-wrap:wrap;gap:var(--gap-width, 0);justify-content:flex-start;align-items:center}:is(#personalizewp) .switcher{display:flex;flex-wrap:wrap;gap:var(--gap-width, 1rem);--threshold: 30rem}:is(#personalizewp) .switcher>*{flex-grow:1;flex-basis:calc((var(--threshold) - 100%)*999)}:is(#personalizewp) .stack{display:grid;grid-template-areas:"stack"}:is(#personalizewp) .stack>*{grid-area:stack}:is(#personalizewp) .flow>*+*{margin-block-start:var(--flow-space, 1em)}:is(#personalizewp) .grid{display:grid;gap:var(--gap-width, 0);grid-template-columns:repeat(var(--grid-auto, auto-fill), minmax(min(100%, var(--grid-min-width, 18rem)), 1fr))}:is(#personalizewp) .repel{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:var(--repel-vertical-alignment, center);gap:var(--gutter, var(--space-s))}:is(#personalizewp) .repel[data-nowrap]{flex-wrap:nowrap}:is(#personalizewp) :where([role=tablist],.nav-list){border-block-end:1px solid var(--color-mid-glare);list-style:"";margin-inline:0;margin-block:0 1.5rem;padding:0;display:flex;gap:var(--gap-width, 2rem);justify-content:flex-start;overflow-x:auto;scroll-behavior:smooth;scroll-snap-type:x proximity}:is(#personalizewp) :where([role=tablist],.nav-list):has(li a:focus-visible){outline:1px dotted var(--color-focus-ring)}:is(#personalizewp) :where([role=tablist],.nav-list) li{margin:0;padding:0;scroll-snap-align:start}:is(#personalizewp) :where([role=tablist],.nav-list) :where([role=tab],.nav-link){float:none;display:block;margin:0;padding-block:.25rem .75rem;padding-inline:0;text-decoration:none;color:var(--color-nav-tab);background-color:rgba(0,0,0,0);font-size:1.25rem;font-weight:600;box-shadow:none;border:none;border-block-end:2px solid rgba(0,0,0,0)}:is(#personalizewp) :where([role=tablist],.nav-list) :where([role=tab],.nav-link):where(:hover,:focus-visible,[aria-selected=true],.is-active){color:var(--color-nav-tab-hover);border-color:var(--color-nav-tab-border)}:is(#personalizewp) :where([role=tablist],.nav-list) :where([role=tab],.nav-link):where(:focus-visible){outline:2px solid var(--color-focus-ring);outline-offset:-2px}:is(#personalizewp)>header.header{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:1.625rem 1rem;margin-block-end:1rem;box-sizing:content-box;width:100%;margin-inline:-20px;padding-block:2.5rem;padding-inline:20px;background-color:#0b2146;background-image:url(../img/header-background.jpg);background-repeat:no-repeat;background-size:cover;background-position:center}:is(#personalizewp)>header.header .title{display:flex;gap:1rem;flex-wrap:wrap;align-items:center;justify-content:center;color:var(--color-light);font-weight:500;font-size:1.5rem;margin-block:0}:is(#personalizewp)>header.header .title .separator{font-weight:100}:is(#personalizewp)>header.header ul,:is(#personalizewp)>header.header li{margin:0}:is(#personalizewp)>header.header .nav-links{display:flex;gap:1rem;list-style:""}:is(#personalizewp)>header.header .nav-links .btn{display:flex;min-width:unset;min-height:unset;white-space:nowrap;background-color:var(--color-light);color:var(--color-secondary);border-color:var(--color-secondary);outline-color:var(--color-focus-ring);font-size:.9375rem;font-weight:600;transition:box-shadow .2s}:is(#personalizewp)>header.header .nav-links .btn:where(:hover,:focus-visible){box-shadow:0 .5rem 1rem rgba(0,0,0,.25);outline-offset:2px;outline-width:2px}@media(max-width: 991px){:is(#personalizewp)>header.header{justify-content:center}:is(#personalizewp)>header.header .nav-links{flex-wrap:wrap}}@media(max-width: 480px){:is(#personalizewp)>header.header .nav-links{flex-direction:column}}:is(#personalizewp) .header-nav{margin-block-end:2rem}:is(#personalizewp) :is(.notice,.notice-message){border-radius:4px;border-color:var(--fill, inherit);color:var(--color-dark)}:is(#personalizewp) :is(.notice,.notice-message).notice{margin-inline:0}:is(#personalizewp) :is(.notice,.notice-message).notice-message:not([class=notice-message]){background:var(--color-light);border:1px solid var(--fill, #c3c4c7);border-left-width:4px;box-shadow:0 1px 1px rgba(0,0,0,.04);padding:1px 12px}:is(#personalizewp) :is(.notice,.notice-message).notice-message:not([class=notice-message]) p{margin-block:.5em;padding:2px}:is(#personalizewp) :is(.notice,.notice-message):where(.notice-error,.notice-warning,.error-message){--fill: var(--color-warning-border);background-color:var(--color-warning-background)}:is(#personalizewp) :is(.notice,.notice-message):where(.notice-success,.success-message){--fill: var(--color-success-border);background-color:var(--color-success-background)}:is(#personalizewp) :is(.notice,.notice-message).notice-info{--fill: var(--color-info-border);background-color:var(--color-info-background)}:is(#personalizewp) :is(.notice,.notice-message) :where(.dashicons){margin-inline-end:.5em;color:var(--fill, inherit)}:is(#personalizewp) :is(.notice,.notice-message)>.dashicons{position:absolute;left:.5em;top:.5em}:is(#personalizewp) :is(.notice,.notice-message)>.dashicons~*{margin-left:2em}:is(#personalizewp) :is(.notice,.notice-message)>.dashicons~input{width:calc(100% - 2em)}:is(#personalizewp) .notice-message{position:relative;margin-inline:0}:is(#personalizewp) .alert{position:relative;font-size:.9375rem;line-height:1.6;border:1px solid rgba(0,0,0,0);border-radius:4px;border-left-width:4px;padding:.75rem 2rem;margin-block-end:0}:is(#personalizewp) .alert .close{padding:.5rem 1rem}:is(#personalizewp) .alert :where(.bi,.dashicons){position:absolute;left:.5em;top:.75em;color:var(--fill, inherit)}:is(#personalizewp) .alert>h2{font-size:15px;line-height:1.6;font-weight:600;margin-bottom:0;color:inherit}:is(#personalizewp) .alert>p{margin-bottom:0}:is(#personalizewp) .alert.alert-danger{--fill: #f5c6cb;background-color:#f8d7da;border-color:#f5c6cb;color:#721c24}:is(#personalizewp) .alert.alert-success{--fill: #42BE65;background-color:#defbe6;border-color:#42be65;color:#1a1a1a}:is(#personalizewp) .alert.alert-info{--fill: #0A1F43;background-color:#fff;border-color:#0a1f43;color:#1a1a1a}:is(#personalizewp) .alert p,:is(#personalizewp) .alert li{font-size:inherit;font-weight:400;line-height:1.6}:is(#personalizewp) .alert p:last-child{margin-bottom:0}:is(#personalizewp) .alert li{list-style-type:"- ";margin-left:1em}:is(#personalizewp) .notice~:where(.notice,.header-nav,main,.section:first-of-type){margin-block-start:2rem}:is(#personalizewp) .section+.section{margin-block-start:2rem}:is(#personalizewp) .section:last-of-type{padding-block-end:2rem}:is(#personalizewp) :where(.section-title,.dashboard-title){font-weight:500;margin-bottom:0;font-size:1.75rem}:is(#personalizewp) .section-subtitle{font-size:1.25rem}:is(#personalizewp) .section-description p{font-size:.9375rem;color:var(--color-dark);clear:both;margin-block-end:0}:is(#personalizewp) .section-description p+p{margin-block-start:1em}:is(#personalizewp) .required{color:var(--required)}:is(#personalizewp) :where(.categories,.rule-usage).with-sidebar{--sidebar-target-width: 28rem}:is(#personalizewp) :where(.profiles,.segments,.scoring-rules).with-sidebar{--sidebar-target-width: 28rem;--gutter: 1rem 2rem}:is(#personalizewp) :where(main).with-sidebar{--sidebar-content-min-width: 60%}:is(#personalizewp) .repel:has(.section-title){--gutter: 1rem 2rem}:is(#personalizewp) .section-description p{max-width:980px}:is(#personalizewp) .context-links{margin:0;display:flex;gap:2.5rem;align-items:center}:is(#personalizewp) .context-links li{margin:0}:is(#personalizewp) .contextual-link[inert]{color:var(--color-mid-glare)}:is(#personalizewp) label+:where(input,select){--flow-space: 0.25em}:is(#personalizewp) .vendor-copyrights{margin-block-start:auto;font-style:italic}:is(#personalizewp) :where(.btn,:where(a,button,input).button){border-radius:4px;border:none;place-content:center;align-items:flex-start;gap:.4em;font-size:1rem;line-height:1.8;text-decoration:none;transition-property:border,background,color;transition-duration:.15s;transition-timing-function:ease-in-out;cursor:pointer}:is(#personalizewp) :where(.btn,:where(a,button,input).button):not([hidden]){display:inline-flex;align-items:center}:is(#personalizewp) :where(.btn,:where(a,button,input).button):has(:where(.dashicons,.icon)){align-items:center;justify-content:flex-start}:is(#personalizewp) :where(.btn,:where(a,button,input).button):where(.btn,.primary,.button-primary,.secondary,.button-secondary){padding:.4rem 1rem;min-width:130px;min-height:42px}:is(#personalizewp) :where(.btn,:where(a,button,input).button):where(.primary,.button-primary){background-color:var(--color-primary);color:var(--color-light)}:is(#personalizewp) :where(.btn,:where(a,button,input).button):where(.primary,.button-primary):where(:hover,:focus):not([disabled]){background:var(--color-light);color:var(--color-primary);outline:2px solid var(--color-primary)}:is(#personalizewp) :where(.btn,:where(a,button,input).button):where(.alt-bg,.secondary,.button-secondary,:not(.primary,.button-primary)){background-color:var(--color-secondary);color:var(--color-light);font-size:.9rem;line-height:2}:is(#personalizewp) :where(.btn,:where(a,button,input).button):where(.alt-bg,.secondary,.button-secondary,:not(.primary,.button-primary)):where(:hover,:focus):not([disabled]){background:var(--color-light);color:var(--color-secondary);outline:2px solid var(--color-secondary)}:is(#personalizewp) :where(.btn,:where(a,button,input).button):where(.disabled,[disabled]){cursor:not-allowed;opacity:.65}:is(#personalizewp) :where(.btn,:where(a,button,input).button)+:where(.btn,.button){margin-left:.5rem}:is(#personalizewp) .chosen-container-single .chosen-single{padding:0 1.5rem 0 .75rem}:is(#personalizewp) [id=pwp-form]{max-width:95rem;display:flex;flex-direction:column}:is(#personalizewp) :is([id=pwp-form],.pwp-form) :where(label,.label){color:#000;font-size:.875rem;font-weight:600;display:flex;gap:.25em;align-items:center;margin-inline:unset;margin-block:0}:is(#personalizewp) :is([id=pwp-form],.pwp-form) :where(label,.label).nowrap{white-space:nowrap}:is(#personalizewp) :is([id=pwp-form],.pwp-form) :where(label,.label)+*{--flow-space: 0.5em}:is(#personalizewp) :is([id=pwp-form],.pwp-form) :where(label,.label)+:where(.description){margin:0;--flow-space: 0.25em}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .description+*{--flow-space: .75em}:is(#personalizewp) :is([id=pwp-form],.pwp-form) :where(.form-group,.conditions-container,.text-field-wrapper)>*+*{margin-top:var(--flow-space, 0.75em)}:is(#personalizewp) :is([id=pwp-form],.pwp-form) input{border-radius:4px;font-size:.875rem;line-height:1}:is(#personalizewp) :is([id=pwp-form],.pwp-form) input:not([type=submit]){padding:0 1.5rem .1em .75rem}:is(#personalizewp) :is([id=pwp-form],.pwp-form) input:not(.is-invalid):not(:invalid){border-color:var(--color-mid-glare)}:is(#personalizewp) :is([id=pwp-form],.pwp-form) input:disabled{background-color:#e9e9e9;position:relative;color:var(--color-dark);border:0}:is(#personalizewp) :is([id=pwp-form],.pwp-form) input:focus{outline:1px solid #0074e7;box-shadow:none}:is(#personalizewp) :is([id=pwp-form],.pwp-form) select{font-size:.875rem;line-height:2.5;border-radius:4px;padding:0 1.5rem 0 .75rem;height:auto;border:1px solid var(--color-mid-glare)}:is(#personalizewp) :is([id=pwp-form],.pwp-form) select:where(:disabled,[inert]){opacity:1;width:100%;background-color:#e9e9e9;position:relative;color:var(--color-dark);border:0}:is(#personalizewp) :is([id=pwp-form],.pwp-form) select:where(:disabled,[inert]).conditions-value{margin-right:0 !important}:is(#personalizewp) :is([id=pwp-form],.pwp-form) select:where(.is-invalid,:invalid)+.chosen-container .chosen-single{border-color:var(--required) !important}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition{display:flex;gap:1rem;align-items:flex-start}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition>*:not(label){width:min(100%,var(--max-input-width, 30rem))}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition[hidden]{display:none !important}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .field-wrapper-styles input{background-color:#fff;border-radius:4px;border-color:var(--color-mid-glare);box-shadow:none;display:flex;align-items:center}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .field-wrapper-styles input::placeholder{color:#444;opacity:.5}@media only screen and (max-width: 600px){:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .field-wrapper-styles input::placeholder{font-size:16px}}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .field-wrapper-styles input:where(:disabled,[inert]){background-color:#e9e9e9}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .field-wrapper-styles input:where(:disabled,[inert])::placeholder{color:var(--color-dark)}@media only screen and (max-width: 600px){:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .field-wrapper-styles input{box-shadow:none;border-color:#8c8f94;border-radius:3px}}@media only screen and (max-width: 600px){:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .field-wrapper-styles{margin-right:0;margin-bottom:10px}}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .days-field-wrapper{display:flex;align-items:center;gap:.75rem}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .days-field-wrapper .datepicker-field{flex:1;min-width:150px}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .days-field-wrapper .equals-sign{font-weight:600;font-size:1.125rem;color:var(--color-primary);flex-shrink:0}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .days-field-wrapper .field-days-number{width:100px;flex-shrink:0;text-align:center}@media only screen and (max-width: 600px){:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .days-field-wrapper{flex-direction:column;gap:.5rem}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .days-field-wrapper .equals-sign{display:none}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .days-field-wrapper .datepicker-field,:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition .days-field-wrapper .field-days-number{width:100%;min-width:auto}}:is(#personalizewp) :is([id=pwp-form],.pwp-form) .condition+*{--flow-space: 1em}:is(#personalizewp) :is([id=pwp-form],.pwp-form) :where([data-condition-count="0"] .condition,[data-condition-count="1"] .condition) .button-conditions-wrapper{visibility:hidden}:is(#personalizewp) .button-conditions-wrapper{display:flex;flex:0}:is(#personalizewp) .button-conditions-wrapper .remove-condition{cursor:pointer;display:flex;background:none;border:0;padding:0}:is(#personalizewp) .button-conditions-wrapper .remove-condition:disabled{opacity:.33;filter:grayscale(1)}:is(#personalizewp) .button-conditions-wrapper button:last-child{margin-right:0}:is(#personalizewp) .add-condition{color:var(--color-secondary);background:none;border:none;border-radius:4px;padding:.5em}:is(#personalizewp) .add-condition:where(:hover,:focus){color:var(--color-primary);cursor:pointer;outline:2px solid var(--color-primary)}:is(#personalizewp) .add-condition:focus-visible{outline:2px solid var(--color-primary)}:is(#personalizewp) .is-invalid~.invalid-feedback{display:block}:is(#personalizewp) .rule-message{color:var(--red);font-size:1rem}:is(#personalizewp) [id=form-actions]{margin-block-start:1.5rem}@media only screen and (max-width: 992px){:is(#personalizewp) .conditions .condition{flex-wrap:wrap}:is(#personalizewp) .conditions .condition>:not(label){margin-bottom:10px}}@media only screen and (max-width: 782px){:is(#personalizewp) .conditions .condition>:not(label){--max-input-width: 20rem}}@media only screen and (max-width: 600px){:is(#personalizewp) .conditions .condition>:not(label){--max-input-width: 100%}}:is(#personalizewp) .dashboard{padding-block:.5rem;--gutter: 2em}:is(#personalizewp) .dashboard:has(>aside.cta-sidebar){max-inline-size:100rem}:is(#personalizewp) .dashboard:has(>aside.cta-sidebar) :where(.pwp-tiles){max-inline-size:unset}:is(#personalizewp) .dashboard-title{border-bottom:1px solid var(--color-mid-glare);padding-bottom:10px;margin-bottom:1rem}:is(#personalizewp) .dashboard-description+*{margin-top:1.5rem}:is(#personalizewp) :where(.pwp-tiles){max-inline-size:68rem;--grid-min-width: 18rem;--gap-width: 2rem 1.5rem;padding-block-end:2rem}:is(#personalizewp) :where(.pwp-tiles).cta-sidebar{margin-inline:0;max-inline-size:unset;align-self:flex-start}:is(#personalizewp) :where(.pwp-tiles) :where(.tile){color:var(--color-dark);background:var(--color-light);box-shadow:0 1px 2px rgba(0,0,0,.15),0 0 2px rgba(0,0,0,.1);border-radius:.5rem;font-size:.875rem;position:relative;overflow:hidden}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) img{width:100%;aspect-ratio:1.77/1;object-fit:cover}:is(#personalizewp) :where(.pwp-tiles) :where(.tile).disabled img{filter:grayscale(1)}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .banner{z-index:1;place-self:center;font-size:.75rem;text-align:center;color:var(--color-light);font-weight:bold}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .banner.coming-soon{border-radius:3rem;background:var(--color-secondary);color:var(--color-light);padding:.5rem .75rem;text-transform:uppercase}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .banner.upgrade a{margin-top:0}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) :where(.tile__content){display:flex;flex-direction:column;padding-block:1rem 2rem;padding-inline:1rem}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) :where(.tile__content)>*{margin:0}:is(#personalizewp) :where(.pwp-tiles) :where(.tile):not(.has-button) .tile__content{padding-inline-end:2.5rem;padding-block-end:1rem}:is(#personalizewp) :where(.pwp-tiles) :where(.tile).has-button .tile__content{align-items:center;text-align:center}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .tile__title{color:inherit;font-size:.875rem;font-weight:bold}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .tile__title+*{--flow-space: .25rem}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .tile__title a{text-decoration:none}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .tile__title a::before{content:"";position:absolute;inset:0}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .tile__title a::after{content:"";position:absolute;bottom:2.5rem;right:.75rem;width:.6rem;height:.6rem;border-top:.15rem solid var(--color-text);border-right:.15rem solid var(--color-text);transform:rotate(45deg) translateX(-0.5rem) translateY(50%);transition:right .2s}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .tile__title a:where(:hover,:focus-within)::after{right:.25rem}:is(#personalizewp) :where(.pwp-tiles) :where(.tile).has-button .tile__title{color:var(--color-dark);font-size:1.25rem}:is(#personalizewp) :where(.pwp-tiles) :where(.tile):where(.disabled,[inert]) .tile__title{color:var(--color-mid-glare)}:is(#personalizewp) :where(.pwp-tiles) :where(.tile) .btn{--flow-space: 1.5rem}:is(#personalizewp) ajax-form{display:block}:is(#personalizewp) [data-tabs]+*{clear:both}:is(#personalizewp) :where(.pwp-panel,ajax-form){padding:min(5vw,2rem);box-shadow:0 1px 2px rgba(0,0,0,.15),0 0 2px rgba(0,0,0,.1);border-radius:4px;background:var(--color-light, #fff);--flow-space: initial}:is(#personalizewp) :where(.pwp-panel,ajax-form)>*{max-width:55rem}:is(#personalizewp) :where(.pwp-panel,ajax-form):not(:last-child){margin-bottom:3rem}:is(#personalizewp) :where(.pwp-panel,ajax-form) :where(.pwp-panel__title,h2){margin-bottom:1.5rem;font-size:1.25rem}:is(#personalizewp) :where(.pwp-panel,ajax-form)>.section-description+*{margin-top:2rem}:is(#personalizewp) :where(.pwp-panel,ajax-form) .form-table p.description{word-break:initial;margin-top:8px}:is(#personalizewp) :where(.pwp-panel,ajax-form) .form-table p.description:first-child{margin-top:0}:is(#personalizewp) :where(.pwp-panel,ajax-form) .form-table th{padding-block:15px;width:18ch}:is(#personalizewp) :where(.pwp-panel,ajax-form) .form-table th label{font-size:1rem;text-wrap:balance}:is(#personalizewp) form .cluster{--gap-width: 1rem}:is(#personalizewp) form .switcher :where(.email,:has(input[type=email])){--threshold: 60rem}:is(#personalizewp) form .switcher :where(.email,:has(input[type=email])) input[type=email]{width:100%}:is(#personalizewp) form label{display:block}:is(#personalizewp) form label a:not(:hover,:focus-within){color:var(--color-secondary)}:is(#personalizewp) form :is(input[type=text],input[type=number],input[type=email],input[type=password],select,textarea){border-color:var(--color-mid-glare);width:min(100%,var(--max-input-width, 40rem));min-height:2.625rem;max-width:unset}:is(#personalizewp) form input.search-icon{background-image:url("../img/search-icon.svg") !important;background-repeat:no-repeat;background-position:center left 8px;padding-left:40px !important}:is(#personalizewp) form .field-error input,:is(#personalizewp) form .field-error textarea{border-color:#d00}:is(#personalizewp) form .input-error{font-size:75%;color:#d00}:is(#personalizewp) form .actions{display:flex;gap:.5em;align-items:flex-start}:is(#personalizewp) .entity-panel{padding-block-end:1px}:is(#personalizewp) .entity-panel>*+*{margin-block-start:var(--flow-space, 3em)}:is(#personalizewp) .entity-panel__nav+*{--flow-space: 1em}:is(#personalizewp) .entity-panel__header{margin-bottom:1rem}:is(#personalizewp) .entity-panel__header h2{margin:0}:is(#personalizewp) .entity-panel .subheading{color:var(--color-text-glare);font-size:1.15em}:is(#personalizewp) .entity-panel table{table-layout:fixed;border-collapse:collapse}:is(#personalizewp) .entity-panel table tr :where(th):not(.check-column,.column-cb){font-weight:bold;padding-right:min(5vw,2rem);min-width:12ch}:is(#personalizewp) .entity-panel table tr :where(td):not(.check-column,.column-cb){min-width:15ch;word-break:break-all}:is(#personalizewp) .entity-panel table tr:not(:last-child) :where(th,td):not(.check-column,.column-cb){padding-bottom:1rem}:is(#personalizewp) .entity-panel input[type=number]{max-width:40ch}:is(#personalizewp) .entity-panel .form-control{max-width:100%}:is(#personalizewp) .entity-panel .form-control.is-invalid+.invalid-feedback{display:block}:is(#personalizewp) .entity-panel .profile-fields table th:first-child{width:35%}:is(#personalizewp) .profile.with-sidebar{--sidebar-target-width: 8.5rem;--sidebar-content-min-width: 75%}:is(#personalizewp) .profile.with-sidebar .profile-fields{max-width:unset !important;align-items:flex-start !important;--gap-width: 1rem;--flow-space: 1.5em}:is(#personalizewp) .profile.with-sidebar .profile-fields>*+*{margin-block-start:var(--flow-space, 2em);margin-block-end:0}:is(#personalizewp) .profile.with-sidebar .lead_score{background:var(--color-secondary-glare);padding:1rem;align-self:flex-start;display:flex;flex-direction:column;text-align:center;gap:.5rem}:is(#personalizewp) .profile.with-sidebar .lead_score h3{font-size:1rem;margin:0}:is(#personalizewp) .profile.with-sidebar .lead_score p{font-size:1.75rem;font-weight:600;margin-block:0}:is(#personalizewp) auto-complete .search{display:flex;position:relative}:is(#personalizewp) auto-complete .search>button{position:absolute;right:0;top:0;bottom:0;border:none;background-color:rgba(0,0,0,0);display:grid;place-content:center}:is(#personalizewp) auto-complete .components-spinner{overflow:visible}:is(#personalizewp) auto-complete .components-spinner path{transform-origin:50% 50% 0px;animation:1.4s linear 0s infinite normal both running rotate-360}:is(#personalizewp) auto-complete .search-results{font-size:.875em;border-radius:4px;background:#fff;box-shadow:0px 0px 4px 0px rgba(0,0,0,.05),0px 4px 8px 0px rgba(0,0,0,.2);max-height:350px;overflow-y:auto;list-style:"" !important;display:flex;flex-flow:column;gap:4px;padding-block:.5em;position:relative;z-index:1000}:is(#personalizewp) auto-complete .search-results:empty{opacity:0;margin-block:0;padding-block:0}:is(#personalizewp) auto-complete .search-results .nothing,:is(#personalizewp) auto-complete .search-results .components-spinner{margin-inline-start:1rem}:is(#personalizewp) auto-complete .search-results li{margin:0;padding:0}:is(#personalizewp) auto-complete .search-results button{cursor:pointer;width:100%;display:flex;flex-direction:column;align-items:flex-start;text-align:left;gap:4px;padding-block:.5rem;padding-inline:1rem;border:none}:is(#personalizewp) auto-complete .search-results button:not(:hover,:focus){background:rgba(0,0,0,0)}:is(#personalizewp) auto-complete .search-results button .header{font-weight:600}:is(#personalizewp) auto-complete .search-results button .info{font-style:italic;padding-inline-start:1em}:is(#personalizewp) auto-complete .search-results [data-type=load-more]{text-align:center;align-items:center;width:max-content;margin-inline:auto}:is(#personalizewp) auto-complete .tag-list:not(:empty){--flow-space: 1rem}:is(#personalizewp) custom-tag-list{--max-input-width: 30rem;display:block}:is(#personalizewp) :where(.tag-list){display:flex;margin:0;margin-block-start:var(--flow-space, 0);--gap-width: 1rem}:is(#personalizewp) :where(.tag-list) :where(li,.tag){list-style:"";display:flex;gap:.25rem;align-items:center;border:none;border-radius:5rem;background-color:var(--color-secondary-glare);color:var(--color-dark);font-size:.875rem;margin:0;padding-block:.25rem;padding-inline:1rem;min-height:2.5rem}:is(#personalizewp) :where(.tag-list) :where(li,.tag) button:not([hidden]){margin-inline-end:-0.75rem}:is(#personalizewp) :where(.tag-list) :where(li,.tag):has(button:where(:hover,:focus),a.trash:where(:hover,:focus)){background-color:var(--color-light);color:var(--color-secondary);outline:2px solid var(--color-secondary)}:is(#personalizewp) :where(.tag-list) :where(li,.tag) a.trash:focus-visible{outline-color:var(--color-primary)}:is(#personalizewp) :where(.tag-list) :where(button,a.trash){min-height:2rem;display:flex;align-items:center}:is(#personalizewp) :where(.tag-list) button,:is(#personalizewp) :where(.tag-list) label{cursor:pointer;margin-block:0}:is(#personalizewp) :where(.tag-list) button{border:none;outline-color:rgba(0,0,0,0);background:rgba(0,0,0,0);color:currentColor;fill:currentColor;padding:0;box-shadow:none}:is(#personalizewp) dialog{border:none;padding:0;animation:dialog-fade-out .25s ease-out}:is(#personalizewp) dialog:not(.onboarding){background-color:var(--color-light);box-shadow:0 0 16px 0 rgba(0,0,0,.25);border-radius:.3rem;width:min(30rem,80%)}:is(#personalizewp) dialog[open]{animation:dialog-fade-in .25s ease-out}:is(#personalizewp) dialog::backdrop{animation:dialog-backdrop-fade-in .25s ease-out forwards;background-color:rgba(0,0,0,.5)}:is(#personalizewp) dialog>*{padding:1rem}:is(#personalizewp) dialog form{display:block}:is(#personalizewp) dialog .dialog-header{display:flex;justify-content:space-between;align-items:flex-start;margin-block-start:0}:is(#personalizewp) dialog .dialog-header :where(button,[type=submit]){cursor:pointer;background-color:rgba(0,0,0,0);border:0;border-radius:.3rem;outline-color:rgba(0,0,0,0);font-size:1.5rem;font-weight:700;line-height:1;color:var(--color-dark);text-shadow:0 1px 0 var(--color-light);opacity:.5;padding:calc(1rem - 4px);margin:calc(-1rem + 4px)}:is(#personalizewp) dialog .dialog-header :where(button,[type=submit]):where(:focus-within,:hover){color:var(--color-dark);opacity:.75}:is(#personalizewp) dialog .dialog-header+*{margin-block-start:var(--flow-space, 1em)}:is(#personalizewp) .table-actions{align-self:flex-end;display:flex;align-items:stretch;flex-wrap:wrap;gap:1.5rem 1rem;justify-content:flex-start}:is(#personalizewp) .table-actions.sidebar{justify-content:flex-end}:is(#personalizewp) .table-actions .search-box{margin-block:0;display:flex;gap:.5rem;align-items:stretch;justify-content:center;flex-wrap:wrap}:is(#personalizewp) .table-actions .search-box input{width:auto}:is(#personalizewp) .table-actions .button,:is(#personalizewp) .table-actions .btn{margin:0}:is(#personalizewp) .table-actions :is(.button,.btn,input[type=text],input[type=submit]){min-height:42px}:is(#personalizewp) .tablenav{display:flex;margin-block:1em;margin-inline:0;padding:0;flex-wrap:wrap;gap:.5em 0;height:auto;justify-content:start;align-items:end}:is(#personalizewp) .tablenav .actions{display:flex;gap:.5em;align-items:stretch}:is(#personalizewp) .tablenav input{width:auto !important;min-height:unset !important}:is(#personalizewp) .tablenav :is(input[type=submit]){min-height:42px}:is(#personalizewp) .tablenav :is(.category-dropdown){border-radius:4px;min-height:42px;border:1px solid var(--color-mid-glare);min-width:12.5em;font-size:.875rem;margin-right:0}:is(#personalizewp) .tablenav .tablenav-pages{float:none;margin-inline-start:auto;margin-block:0}@media screen and (min-width: 783px){:is(#personalizewp) .tablenav .pagination-links{display:inline-flex;align-items:baseline;gap:4px}}:is(#personalizewp) .tablenav .button{background-color:rgba(0,0,0,0);color:inherit;border:1px solid var(--color-secondary)}:is(#personalizewp) .tablenav .button:not(:where([disabled],.disabled)):where(:hover,:focus){border-color:var(--color-primary);outline:2px solid var(--color-primary)}:is(#personalizewp) .subsubsub{margin:0}:is(#personalizewp) .subsubsub li a{border:1px solid var(--border-color, var(--color-mid-glare));font-size:.875rem;display:inline-block;padding-inline:1rem;padding-block:.3125rem}:is(#personalizewp) .subsubsub li a:where(:hover,:focus-visible,.current){background:var(--color-primary-glare);text-decoration:none}:is(#personalizewp) .subsubsub li a:where(:focus-visible){outline-color:var(--color-primary)}:is(#personalizewp) .subsubsub li a.current{--border-color: var(--color-primary)}:is(#personalizewp) .subsubsub li:first-of-type a{border-start-start-radius:4px;border-end-start-radius:4px}:is(#personalizewp) .subsubsub li:first-of-type a:not(.current){border-inline-end-width:0}:is(#personalizewp) .subsubsub li:last-of-type a{border-start-end-radius:4px;border-end-end-radius:4px}:is(#personalizewp) .subsubsub li:last-of-type a:not(.current){border-inline-start-width:0}@media screen and (min-width: 1100px){:is(#personalizewp) .column-usage_blocks,:is(#personalizewp) .column-activity_type,:is(#personalizewp) .column-contact_count,:is(#personalizewp) .column-created{width:20ch}:is(#personalizewp) .column-lead_score{width:15ch}}:is(#personalizewp) .wp-list-table{border:1px solid rgba(0,0,0,.1);border-radius:4px;border-collapse:separate !important}:is(#personalizewp) .wp-list-table.api_key_table{margin-block-start:1rem;margin-block-end:2rem}:is(#personalizewp) .wp-list-table.api_key_table caption{font-weight:bold;color:inherit;caption-side:top;padding-block:.75em;text-align:start}:is(#personalizewp) .wp-list-table th,:is(#personalizewp) .wp-list-table td{font-size:.9375rem}:is(#personalizewp) .wp-list-table th:where(.column-count),:is(#personalizewp) .wp-list-table td:where(.column-count){text-align:center}:is(#personalizewp) .wp-list-table th{font-weight:700}:is(#personalizewp) .wp-list-table th:not(.check-column,.column-cb){padding-block:1rem;padding-inline:1rem}:is(#personalizewp) .wp-list-table th:where(.sortable,.sorted) a{padding:0;color:inherit}:is(#personalizewp) .wp-list-table th:where(.column-count) a{display:flex;justify-content:center}:is(#personalizewp) .wp-list-table th:where(.column-count) a>span{float:none}:is(#personalizewp) .wp-list-table th:where(.column-lead_score,.column-contact_count) a{display:flex;justify-content:center}:is(#personalizewp) .wp-list-table th:where(.column-lead_score,.column-contact_count) a>span{float:none}@media screen and (min-width: 783px){:is(#personalizewp) .wp-list-table td:not(.check-column,.column-cb){padding-block:.5rem;padding-inline:1rem}:is(#personalizewp) .wp-list-table td:where(.column-lead_score,.column-contact_count){text-align:center}}:is(#personalizewp) .wp-list-table tbody tr:hover{background-color:#f8f8f8}:is(#personalizewp) .wp-list-table tbody>:nth-child(2n+1){background-color:inherit}:is(#personalizewp) .wp-list-table tbody>:not(:last-child)>:where(th,td){border-bottom:1px solid var(--color-mid-glare)}:is(#personalizewp) dialog.onboarding{height:100vh;width:100vw}:is(#personalizewp) dialog.onboarding .wrapper{padding:0;height:100%;width:100%;display:grid;grid-template-areas:"aside main" "aside footer";grid-template-columns:0px auto;grid-template-rows:1fr auto}@media(min-width: 768px){:is(#personalizewp) dialog.onboarding .wrapper{grid-template-columns:112px auto}}:is(#personalizewp) dialog.onboarding .wrapper aside{grid-area:aside}:is(#personalizewp) dialog.onboarding .wrapper article{grid-area:main}:is(#personalizewp) dialog.onboarding .wrapper>footer{grid-area:footer}:is(#personalizewp) dialog.onboarding aside{display:flex;justify-content:center;align-items:center;color:var(--color-light, #fff);background-color:var(--color-secondary);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='92' height='146' fill='none' viewBox='0 0 92 146'%3E%3Ccircle cx='73' cy='73' r='73' fill='url(%23pink_shape)' transform='matrix(0 -1 -1 0 92 146)'/%3E%3CradialGradient id='pink_shape' cx='0' cy='0' r='1' gradientTransform='rotate(139 112 19) scale(215)' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%23D300A5'/%3E%3Cstop offset='1' stop-color='%23542A73' stop-opacity='0'/%3E%3C/radialGradient%3E%3C/svg%3E%0A");background-repeat:no-repeat;background-position:bottom left;overflow:hidden}:is(#personalizewp) dialog.onboarding aside nav form{display:flex;place-content:center;align-items:center;margin-block-end:1rem}:is(#personalizewp) dialog.onboarding aside nav form button{border-color:rgba(138,141,143,.2)}:is(#personalizewp) dialog.onboarding aside nav button{display:flex;border:2px solid rgba(0,0,0,0);background-color:rgba(0,0,0,0);color:inherit;aspect-ratio:1;padding:.5em}:is(#personalizewp) dialog.onboarding aside nav button[disabled]{cursor:auto;opacity:inherit;border-color:rgba(0,0,0,0) !important;background-color:rgba(0,0,0,0) !important;color:inherit !important}:is(#personalizewp) dialog.onboarding aside nav button:where(:hover,:focus-visible):not([disabled]){border-color:rgba(138,141,143,.6)}:is(#personalizewp) dialog.onboarding aside nav button:where(:hover,:focus-visible):not([disabled]) svg{opacity:.6 !important}:is(#personalizewp) dialog.onboarding article{padding:0;display:flex}:is(#personalizewp) dialog.onboarding section{flex:1;display:flex;flex-direction:column}:is(#personalizewp) dialog.onboarding section>*{padding-block:2rem;padding-inline:clamp(1.25rem,.6875rem + 2.8125vi,3.5rem)}:is(#personalizewp) dialog.onboarding header{display:flex;gap:1rem;align-items:start;min-height:10rem;background-color:var(--color-secondary-glare);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='526' height='220' fill='none' viewBox='0 0 526 220'%3E%3Cg fill-opacity='.1' opacity='.4'%3E%3Cpath fill='url(%23grey_shape1)' d='M321 110 232-48A124 124 0 1 0 16 74l90 158a124 124 0 1 0 215-122Z'/%3E%3Cpath fill='url(%23grey_shape2)' d='M403 178a123 123 0 1 0 0-246 123 123 0 0 0 0 246Z'/%3E%3C/g%3E%3Cdefs%3E%3CradialGradient id='grey_shape1' cx='0' cy='0' r='1' gradientTransform='matrix(173 -173 144 144 87 295)' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%230A1F43'/%3E%3Cstop offset='1' stop-color='%230A1F43' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='grey_shape2' cx='0' cy='0' r='1' gradientTransform='matrix(129 -129 120 120 343 178)' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%230A1F43'/%3E%3Cstop offset='1' stop-color='%230A1F43' stop-opacity='0'/%3E%3C/radialGradient%3E%3C/defs%3E%3C/svg%3E%0A");background-repeat:no-repeat;background-position:bottom right}:is(#personalizewp) dialog.onboarding header h1{font-size:1.75rem}:is(#personalizewp) dialog.onboarding header img,:is(#personalizewp) dialog.onboarding header svg{flex-shrink:0;margin-inline-start:auto}:is(#personalizewp) dialog.onboarding .content{flex:1}:is(#personalizewp) dialog.onboarding .content :where(img){display:block;max-width:100%;width:100%;height:auto}:is(#personalizewp) dialog.onboarding .content :where(p){margin-bottom:0}:is(#personalizewp) dialog.onboarding .content :where(p):not([class]){max-width:70ch}:is(#personalizewp) dialog.onboarding .content :where(iframe){width:100%;height:auto;aspect-ratio:16/9}:is(#personalizewp) dialog.onboarding .content :where(label,.label){font-weight:normal}:is(#personalizewp) dialog.onboarding :where(.onboard-cards){--gap-width: 1.75rem;--grid-auto: auto-fit;--grid-min-width: min(40%, 16rem);margin-block:2rem}:is(#personalizewp) dialog.onboarding :where(.onboard-cards):has(:nth-child(4)){--grid-min-width: min(40%, 10rem)}:is(#personalizewp) dialog.onboarding :where(.onboard-cards) :where(.onboard-card){display:flex;flex-direction:column;align-items:center;text-align:center}:is(#personalizewp) dialog.onboarding .switcher.onboard-cards{--threshold: 40rem}:is(#personalizewp) dialog.onboarding .stack.video{width:min(100%,45rem);margin-inline:auto;margin-block-start:1em;overflow:hidden;border-radius:1.5rem;box-shadow:0px 2px 1.5rem -4px rgba(10,31,67,.2)}:is(#personalizewp) dialog.onboarding .stack.video .overlay{order:1;display:grid;place-content:center}:is(#personalizewp) dialog.onboarding .stack.video button{aspect-ratio:1;padding:20px;border:none;border-radius:50%;background:linear-gradient(90deg, #C127A0 0%, #F20FA6 100%)}:is(#personalizewp) dialog.onboarding .stack.video button:where(:hover,:focus){border:4px solid var(--color-light, #fff);outline:2px solid rgba(0,0,0,0)}:is(#personalizewp) dialog.onboarding .stack.video button svg{max-height:100%;width:auto;transform:translateX(2px)}:is(#personalizewp) dialog.onboarding img.aligncenter{max-width:min(28rem,70vw);margin-inline:auto}:is(#personalizewp) dialog.onboarding footer.next-step{margin-block-start:auto;padding-block-end:0;display:flex;place-content:center}:is(#personalizewp) dialog.onboarding .cluster.checkmarks{--gap-width: 0}:is(#personalizewp) dialog.onboarding label.checkmark{cursor:pointer;margin:0;display:flex;gap:.4em;justify-content:center;align-items:center;width:auto;padding-block:.375rem;padding-inline:1.5rem .75rem;border:1px solid #ced4da;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}:is(#personalizewp) dialog.onboarding label.checkmark:first-child{border-top-left-radius:40px;border-bottom-left-radius:40px}:is(#personalizewp) dialog.onboarding label.checkmark:not(:last-child){border-right-color:rgba(0,0,0,0)}:is(#personalizewp) dialog.onboarding label.checkmark:last-child{border-top-right-radius:40px;border-bottom-right-radius:40px}:is(#personalizewp) dialog.onboarding label.checkmark input{clip:rect(1px, 1px, 1px, 1px);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}:is(#personalizewp) dialog.onboarding label.checkmark input:before{display:none}:is(#personalizewp) dialog.onboarding label.checkmark svg{opacity:0;flex-shrink:0}:is(#personalizewp) dialog.onboarding label.checkmark:focus-within{outline:max(2px,.15em) solid currentColor;outline-offset:max(2px,.15em)}:is(#personalizewp) dialog.onboarding label.checkmark:where(:hover,:focus-within) svg{opacity:.2}:is(#personalizewp) dialog.onboarding label.checkmark:has(input:checked){background-color:rgba(193,39,160,.25);border-color:#000}:is(#personalizewp) dialog.onboarding label.checkmark:has(input:checked) svg{opacity:1}:is(#personalizewp) dialog.onboarding form{margin:0;padding:0;box-shadow:none;background-color:rgba(0,0,0,0);max-width:45rem}:is(#personalizewp) dialog.onboarding :where(.wizard-progress){display:flex;place-content:center;align-items:center;margin:0;padding:0;list-style:""}:is(#personalizewp) dialog.onboarding :where(.wizard-progress) li{margin:0}:is(#personalizewp) dialog.onboarding :where(.wizard-progress).icons{flex-direction:column;gap:.25rem;--line-width: .3125rem}:is(#personalizewp) dialog.onboarding :where(.wizard-progress).icons li+li:before{display:block;content:"";position:relative;top:0;left:calc(50% - var(--line-width)/2);width:var(--line-width);height:2rem;background-color:rgba(138,141,143,.2);border-radius:calc(var(--line-width)/2)}:is(#personalizewp) dialog.onboarding :where(.wizard-progress).icons li:where(:not(.is-active,:focus-within)) svg{opacity:.2}:is(#personalizewp) dialog.onboarding :where(.wizard-progress).dots{padding-block:2rem;gap:1rem;--line-width: 1.25rem;--line-height: .625rem;--line-color: #d9d9d9}:is(#personalizewp) dialog.onboarding :where(.wizard-progress).dots li{height:var(--line-height);width:var(--line-width);border-radius:calc(var(--line-height)/2);background-color:var(--line-color);color:var(--line-color);transition:all 300ms ease}:is(#personalizewp) dialog.onboarding :where(.wizard-progress).dots li:where(.is-active){--line-width: 3.75rem;--line-color: #C127A0}:is(#personalizewp) .discount-offer-block{background-color:#f10fa6 !important;margin-top:-1rem;margin-top:-1rem;padding:1rem 1.5rem;display:flex;flex-direction:row;justify-content:center;align-items:center;margin-bottom:1rem}:is(#personalizewp) .discount-offer-block .discount-offer-text{color:#fff;margin-bottom:0;text-align:center;line-height:1.5rem}:is(#personalizewp) .discount-offer-block .discount-offer-text a{color:#fff !important;text-decoration:none !important;border-bottom:1px solid #fff;padding-bottom:2px}:is(#personalizewp) .discount-offer-block .discount-offer-text a:hover{cursor:pointer !important}@keyframes rotate-360{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes dialog-fade-in{0%{opacity:0;transform:translateY(-2rem);display:none}100%{opacity:1;transform:translateY(0);display:block}}@keyframes dialog-fade-out{0%{opacity:1;transform:translateY(0);display:block}100%{opacity:0;transform:translateY(-2rem);display:none}}@keyframes dialog-backdrop-fade-in{0%{background-color:rgba(0,0,0,0)}100%{background-color:rgba(0,0,0,.5)}}
  • personalizewp/trunk/admin/css/editor-content.css

    r3452048 r3458877  
    11@charset "UTF-8";
    2 /*! PersonalizeWP v3.4.0 | (c) 2026 PersonalizeWP | GPL-3.0 License */
     2/*! PersonalizeWP v3.4.1 | (c) 2026 PersonalizeWP | GPL-3.0 License */
    33.personalizewp__has-been-personalized {
    44    outline: 2px dashed rgb(241, 15, 166);
  • personalizewp/trunk/admin/css/editor-content.min.css

    r3452048 r3458877  
    11@charset "UTF-8";
    2 /*! PersonalizeWP v3.4.0 | (c) 2026 PersonalizeWP | GPL-3.0 License */
     2/*! PersonalizeWP v3.4.1 | (c) 2026 PersonalizeWP | GPL-3.0 License */
    33.personalizewp__has-been-personalized{outline:2px dashed #f10fa6}.personalizewp__has-been-personalized::before{content:attr(data-personalized-label);display:inline-block;position:absolute;inset-block-start:-1rem;inset-inline-start:-0.15rem;background-color:rgba(241,15,66,.15);border-top-left-radius:1rem;color:#000;font-size:.5rem;line-height:normal;padding-block:.25em;padding-inline:1em;padding-inline-start:calc(.625rem + 1px);pointer-events:none}:is(*.is-selected+.personalizewp__has-been-personalized,.personalizewp__has-been-personalized.is-selected)::before{display:none}pwp-user-data:not(:defined){outline:2px dashed hotpink;position:relative}pwp-user-data:not(:defined)::before{content:"PWP:" attr(data);display:block;position:absolute;inset-block-start:-1.5em;inset-inline-end:0;background-color:#fff;color:#d3d3d3;padding:0 2px;font-size:10px;font-style:italic}
  • personalizewp/trunk/admin/css/editor.css

    r3452048 r3458877  
    11@charset "UTF-8";
    2 /*! PersonalizeWP v3.4.0 | (c) 2026 PersonalizeWP | GPL-3.0 License */
     2/*! PersonalizeWP v3.4.1 | (c) 2026 PersonalizeWP | GPL-3.0 License */
    33.components-panel input:is([type=url], [type=email], [type=number]):where(:disabled, .disabled) {
    44    background-color: var(--wp-components-color-gray-100, #f0f0f0);
  • personalizewp/trunk/admin/css/editor.min.css

    r3452048 r3458877  
    11@charset "UTF-8";
    2 /*! PersonalizeWP v3.4.0 | (c) 2026 PersonalizeWP | GPL-3.0 License */
     2/*! PersonalizeWP v3.4.1 | (c) 2026 PersonalizeWP | GPL-3.0 License */
    33.components-panel input:is([type=url],[type=email],[type=number]):where(:disabled,.disabled){background-color:var(--wp-components-color-gray-100, #f0f0f0);border-color:var(--wp-components-color-gray-400, #ccc);border-radius:2px}.components-panel input:is([type=url],[type=email],[type=number]):where(:disabled,.disabled)::placeholder{color:var(--wp-components-color-gray-600, #949494)}.components-panel .pwp-panel:not(.password,.integrations-fields){position:relative;margin-top:18px;padding-top:16px;border-top:1px solid rgba(196,196,196,.631372549)}.components-panel .pwp-panel:where(.rules,.segments,.profile-fields,.integrations-fields) .components-base-control,.components-panel .pwp-panel:where(.rules,.segments,.profile-fields,.integrations-fields) .components-base-control__field{margin-bottom:0;width:100%}.components-panel .pwp-panel:where(.rules,.segments,.profile-fields,.integrations-fields) .components-button{padding:0;height:30px;min-width:min-content}.components-panel .pwp-panel:where(.rules,.segments,.integrations-fields) .select-rule+.select-rule,.components-panel .pwp-panel:where(.rules,.segments,.integrations-fields) .select-integrations-plan+.select-integrations-plan{margin-top:.5em}.components-panel .pwp-panel:where(.rules,.segments,.integrations-fields) .help{margin-block:0}.components-panel .pwp-panel.profile-fields .profile-field{display:grid;gap:8px}.components-panel .pwp-panel.profile-fields .profile-field+.profile-field{margin-top:16px}.components-panel .pwp-panel.action{margin-bottom:2px}.components-panel .pwp-panel.action::before{content:"THEN";display:block;position:absolute;top:-0.6rem;left:calc(50% - (2ch + 1em));padding-inline:1em;background-color:#fff;font-size:.9rem;font-weight:bold}.components-panel .pwp-panel .rule-set__add-rule{margin-top:12px}.components-panel .pwp-panel :where(.bi,.dashicons,button svg){width:24px;height:24px;aspect-ratio:1;cursor:pointer}.components-panel .pwp-panel button:disabled :where(.bi,.dashicons,svg){cursor:default}.components-panel .pwp-panel .score-error{margin-inline:-15px}.components-panel .pwp-panel .score-error>*{margin-inline:0;margin-block-end:1em}.components-panel .pwp-panel .pwp-toggle label{flex:initial;cursor:pointer}.components-panel .pwp-panel .search-option-selected{display:grid;grid-template-columns:repeat(2, 1fr);gap:5px}.components-panel .pwp-panel .search-option-selected .search-option-selected-item{padding:8px;background:#f9f9f9}.components-panel .pwp-panel .components-search-control .components-input-control__container{background-color:#fff;border:1px solid var(--wp-components-color-gray-600, #949494)}.components-panel .pwp-panel .components-disabled .components-search-control .components-input-control__container{background-color:var(--wp-components-color-gray-100, #f0f0f0);border:none}.block-editor-format-toolbar__personalizewp-popover .components-popover__content{padding:1rem;width:auto}
  • personalizewp/trunk/includes/class-api.php

    r3382403 r3458877  
    553553     * @param string $url  URL to sanitise to match browser origin format
    554554     *
    555      * @return string Sanitised URL
     555     * @return string Sanitised URL or empty
    556556     */
    557557    public function sanitize_origin_url( $url ) {
    558558
    559559        $_parts = wp_parse_url( $url );
    560         $url    = untrailingslashit( sprintf( '%s://%s', $_parts['scheme'], $_parts['host'] ) );
     560        if ( empty( $_parts['scheme'] ) || empty( $_parts['host'] ) ) {
     561            return '';
     562        }
     563        $url = untrailingslashit( sprintf( '%s://%s', $_parts['scheme'], $_parts['host'] ) );
    561564
    562565        return $url;
  • personalizewp/trunk/includes/class-db-manager.php

    r3422812 r3458877  
    1212
    1313use PersonalizeWP\Traits\SingletonTrait;
     14use PersonalizeWP\Model\Contact;
     15use PersonalizeWP\Integrations\WooCommerce\WooCommerce_Memberships_Teams;
    1416
    1517defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
     
    3739     * @var int
    3840     */
    39     const DB_VERSION = 330; // Increment with each change in db
     41    const DB_VERSION = 341; // Increment with each change in db
    4042
    4143    /**
     
    6466        // Immediately check for possible database migrations, since already within `init` hook.
    6567        $this->check_migrate();
     68
     69        add_action( 'personalizewp_batch_user_memberships_team_backfill', array( $this, 'batch_user_memberships_team_backfill' ) );
    6670    }
    6771
     
    134138        if ( $current_db_version < 330 ) {
    135139            $this->upgrade_330( $current_db_version );
     140        }
     141
     142        if ( $current_db_version < 341 ) {
     143            $this->upgrade_341( $current_db_version );
    136144        }
    137145
     
    360368            $this->install_tables();
    361369        }
     370    }
     371
     372    /**
     373     * Executes changes made in 3.4.1.
     374     *
     375     * @since 3.4.1
     376     *
     377     * @param int $db_version The old (current) database version.
     378     *
     379     * @return void
     380     */
     381    private function upgrade_341( $db_version ) {
     382        global $wpdb;
     383
     384        if ( $db_version < 341 ) {
     385
     386            // Check for use of Teams, no need to run if not. Cannot check for our Teams class as this upgrade runs early.
     387            if ( ! class_exists( 'WC_Memberships_For_Teams_Loader' ) ) {
     388                return;
     389            }
     390            // Safety check for Action Scheduler, which is core within WooCommerce and needed for backfilling.
     391            if ( ! function_exists( 'as_enqueue_async_action' ) ) {
     392                return;
     393            }
     394
     395            // 1: Get all Visitor IDs with corresponding WP User ID meta, without a teams meta field ID
     396            $visitor_ids = $wpdb->get_col(
     397                $wpdb->prepare(
     398                    'SELECT meta1.contact_id
     399                    FROM %i as meta1
     400                    LEFT JOIN %i as meta2 ON ( meta1.contact_id = meta2.contact_id AND meta2.meta_key = %s )
     401                    WHERE meta1.meta_key = %s AND meta2.contact_id IS NULL',
     402                    $wpdb->prefix . 'pwp_contacts_meta',
     403                    $wpdb->prefix . 'pwp_contacts_meta',
     404                    'wc_memberships_team_id',
     405                    'wp_user_id'
     406                )
     407            );
     408
     409            $action_ids = array();
     410            // 2: Add new AS action for each found Visitor ID.
     411            foreach ( $visitor_ids as $visitor_id ) {
     412                $action_ids[] = as_enqueue_async_action(
     413                    'personalizewp_batch_user_memberships_team_backfill',
     414                    array( $visitor_id ),
     415                    'personalizewp_memberships_teams'
     416                );
     417            }
     418        }
     419    }
     420
     421    /**
     422     * Backfills a visitors Team ID for WooCommerce Memberships.
     423     *
     424     * @param int $visitor_id Visitor ID
     425     *
     426     * @return int|bool|WP_Error|void Returns early if the user doesn't exist, or the team is already set
     427     */
     428    public function batch_user_memberships_team_backfill( $visitor_id ) {
     429
     430        // Safety check
     431        $teams = WooCommerce_Memberships_Teams::instance();
     432        if ( empty( $teams ) ) {
     433            return new \WP_Error( 'personalizewp_teams_backfill_teams_not_available', __( 'Teams for WooCommerce Memberships not available', 'personalizewp' ) );
     434        }
     435
     436        // Check visitor ID validity.
     437        $visitor = Contact::get_instance( $visitor_id );
     438        if ( ! $visitor ) {
     439            return new \WP_Error( 'personalizewp_teams_backfill_invalid_visitor', __( 'Invalid Visitor ID', 'personalizewp' ) );
     440        }
     441
     442        // Double check for pre-existing memberships team.
     443        $_team_id = $visitor->get_metadata( 'wc_memberships_team_id', true );
     444        if ( ! empty( $_team_id ) ) {
     445            return;
     446        }
     447
     448        // Get WP User ID, *should* be valid.
     449        $wp_user_id = $visitor->get_metadata( 'wp_user_id', true );
     450        $team_id    = $teams->get_membership_team_id_by_user_id( $wp_user_id );
     451        if ( empty( $team_id ) ) {
     452            // No valid team, nothing to do.
     453            return;
     454        }
     455
     456        // Add/update new meta data
     457        return $visitor->update_metadata( 'wc_memberships_team_id', $team_id );
    362458    }
    363459
  • personalizewp/trunk/includes/class-publicfacing.php

    r3422812 r3458877  
    107107         * @since 3.1.0
    108108         *
    109          * @param string[] $pwp_settings String indexed array of PersonalizeWP settings.
     109         * @param array[] $pwp_settings {
     110         *     String indexed array of PersonalizeWP settings for the core JS.
     111         *
     112         *     @type array ...$0 {
     113         *         An associative array of the variables.
     114         *
     115         *         @type string $root          URL root for all PersonalizeWP REST requests.
     116         *         @type string $nonceEndpoint URL endpoint for JS to retrieve a new nonce when visitor is logged in.
     117         *         @type bool   $isLoggedIn    Flag which triggers sending a 'X-WP-Nonce' header with REST calls to ensure no CSRF for users. Default false.
     118         *         @type bool   $delayInit     Flag to indicate the PersonalizeWP JavaScript should delay itself until some user interaction has occurred. Default false.
     119         *         @type string $apiToken      Token to restrict API responses to known domains, i.e. CSP authorisation.
     120         *     }
     121         * }
    110122         */
    111123        $pwp_settings = apply_filters(
    112124            'personalizewp_js_settings',
    113125            array(
    114                 'root'      => sanitize_url( get_rest_url() ), // phpcs:ignore WordPress.WP.DeprecatedFunctions.sanitize_url -- 5.9 un-deprecated this
    115                 'nonce'     => wp_create_nonce( 'wp_rest' ), // Required for checking on logged in status
    116                 'delayInit' => (bool) $this->plugin->get_setting( 'performance_delay_initialisation' ),
    117                 'apiToken'  => $this->plugin->api->get_api_auth_token( get_home_url() ),
     126                'root'          => sanitize_url( get_rest_url() ), // phpcs:ignore WordPress.WP.DeprecatedFunctions.sanitize_url -- 5.9 un-deprecated this
     127                'nonceEndpoint' => admin_url( 'admin-ajax.php?action=rest-nonce' ),
     128                'isLoggedIn'    => is_user_logged_in(),
     129                'delayInit'     => (bool) $this->plugin->get_setting( 'performance_delay_initialisation' ),
     130                'apiToken'      => $this->plugin->api->get_api_auth_token( get_home_url() ),
    118131            )
    119132        );
     
    193206        // We do this as the JS data will be part of the cached HTML.
    194207        $args = array(
    195             'trackAnon' => $this->plugin->should_track_anonymous_users(),
    196             'type'      => 'misc',
    197         );
    198         if ( is_user_logged_in() ) {
    199             // Frontend should not be cached and will be known.
    200             $args['userIsKnown'] = true;
    201         }
     208            'trackAnon'   => $this->plugin->should_track_anonymous_users(),
     209            'userIsKnown' => is_user_logged_in(), // Frontend should not be cached and will be known.
     210            'type'        => 'misc',
     211            'obj'         => null,
     212        );
    202213        if ( is_home() || is_front_page() ) {
    203214            $args['type'] = 'home';
     
    237248         * @since 3.3.0
    238249         *
    239          * @param array $args JS variables to pass to the PWP Tracking module
     250         * @param array[] $args {
     251         *     JS variables to pass to the PWP Tracking module.
     252         *
     253         *     @type array ...$0 {
     254         *         An associative array of the variables.
     255         *
     256         *         @type bool     $trackAnon   Flag to indicate to tracking JS if anonymous users should be tracked or not. Default false.
     257         *         @type bool     $userIsKnown Flag to indicate current visitor is known to the site. Default false.
     258         *         @type string   $type        Type of event being tracked.
     259         *         @type int|null $obj         Object ID of current CPT or Taxonomy, default to null.
     260         *     }
     261         * }
    240262         */
    241263        return apply_filters( 'personalizewp_get_tracking_variables', $args );
  • personalizewp/trunk/includes/integrations/woocommerce/class-woocommerce-memberships-teams.php

    r3452048 r3458877  
    112112    public function is_profile_listing_screen(): bool {
    113113        $screen = get_current_screen();
    114         return is_object( $screen ) && 'admin_page_' . PageContacts::SLUG === $screen->id;
     114        return is_object( $screen ) && str_ends_with( $screen->id, PageContacts::SLUG );
    115115    }
    116116
     
    123123    public function is_recent_events_screen(): bool {
    124124        $screen = get_current_screen();
    125         return is_object( $screen ) && 'personalize_page_' . PageActivities::SLUG === $screen->id;
     125        return is_object( $screen ) && str_ends_with( $screen->id, PageActivities::SLUG );
    126126    }
    127127
     
    134134    public function is_team_profile_screen(): bool {
    135135        $screen          = get_current_screen();
    136         $is_profile_page = is_object( $screen ) && 'admin_page_' . PageContacts::SLUG === $screen->id;
     136        $is_profile_page = is_object( $screen ) && str_ends_with( $screen->id, PageContacts::SLUG );
    137137        $action          = isset( $_REQUEST[ Admin::URL_ACTION ] ) ? sanitize_text_field( wp_unslash( $_REQUEST[ Admin::URL_ACTION ] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: nonce verification not required
    138138        $is_team_profile = 'view-team' === $action;
  • personalizewp/trunk/package.json

    r3452048 r3458877  
    22  "name": "personalizewp",
    33  "title": "PersonalizeWP",
    4   "version": "3.4.0",
     4  "version": "3.4.1",
    55  "description": "PersonalizeWP plugin",
    66  "author": "PersonalizeWP",
  • personalizewp/trunk/personalizewp.php

    r3452048 r3458877  
    1111 * Plugin URI:        https://personalizewp.com/
    1212 * Description:       Add powerful personalization features to your WordPress site. Show different content to different visitors based on their behavior, profile, location, and more.
    13  * Version:           3.4.0
     13 * Version:           3.4.1
    1414 * Author:            Filter
    1515 * Author URI:        https://filter.agency/
     
    4040 * Current plugin version.
    4141 */
    42 define( 'PERSONALIZEWP_VERSION', '3.4.0' );
     42define( 'PERSONALIZEWP_VERSION', '3.4.1' );
    4343
    4444// Load autoloader.
  • personalizewp/trunk/public/css/pwp.css

    r3452048 r3458877  
    11@charset "UTF-8";
    2 /*! PersonalizeWP v3.4.0 | (c) 2026 PersonalizeWP | GPL-3.0 License */
     2/*! PersonalizeWP v3.4.1 | (c) 2026 PersonalizeWP | GPL-3.0 License */
    33:where(pwp-block, wp-dxp):empty,
    44:where(pwp-block, wp-dxp):not(:defined) {
  • personalizewp/trunk/public/css/pwp.min.css

    r3452048 r3458877  
    11@charset "UTF-8";
    2 /*! PersonalizeWP v3.4.0 | (c) 2026 PersonalizeWP | GPL-3.0 License */
     2/*! PersonalizeWP v3.4.1 | (c) 2026 PersonalizeWP | GPL-3.0 License */
    33:where(pwp-block,wp-dxp):empty,:where(pwp-block,wp-dxp):not(:defined){display:none !important}:where(pwp-content-variations):where(:defined:not([hidden]),:not(:defined)){display:block}:where(pwp-block-pwd):not(:defined){display:none}:where(pwp-block-pwd):defined{display:block}:where(.personalizewp-password-form) :where(.personalizewp-password-form-input input){display:block;font:inherit;padding:calc(.332em + 2px) calc(.667em + 2px);border:1px solid silver;border-radius:.225rem}:where(.personalizewp-password-form) :where([aria-invalid=true]){outline:2px solid red}:where(.personalizewp-password-form) :where([aria-invalid=true])~:where(.invalid-feedback){display:block;visibility:visible}
  • personalizewp/trunk/public/js/pwp.asset.php

    r3452048 r3458877  
    1 <?php return array('dependencies' => array('wp-hooks'), 'version' => 'ed34d7f38f5bb44053fc');
     1<?php return array('dependencies' => array('wp-hooks'), 'version' => 'f39dfd52965eae76aa5b');
  • personalizewp/trunk/public/js/pwp.js

    r3452048 r3458877  
    1 (()=>{"use strict";const e=window.wp.hooks;window.PersonalizeWP=function(t,n){let o={pwpGet:(e,t=!1,n="personalizewp")=>{const o=localStorage.getItem(`${n}_${e}`);return o?t?JSON.parse(o):o:null},pwpStore:(e,t,n="personalizewp")=>{localStorage.setItem(`${n}_${e}`,JSON.stringify(t))},pwpClear:(e,t="personalizewp")=>{localStorage.removeItem(`${t}_${e}`)},callApi:async(e,t)=>{try{const n=await fetch(`${a}${e}`,{mode:"cors",method:"POST",cache:"no-cache",headers:{Accept:"application/json, */*;q=0.1","Cache-Control":"no-cache","Content-type":"application/json","X-Requested-With":"XMLHttpRequest",...window.pwpSettings&&window.pwpSettings.apiToken&&{"X-PWP-Auth-Token":window.pwpSettings.apiToken},...window.pwpSettings&&window.pwpSettings.nonce&&{"X-WP-Nonce":window.pwpSettings.nonce}},body:JSON.stringify(t)});if(!n.ok)throw new Error(`Response status: ${n.status}`);return await n.json()}catch(e){console.warn("API Error:",e)}return null},nodeScriptReplace:e=>{if("SCRIPT"===e.tagName)e.parentNode.replaceChild(o.nodeScriptClone(e),e);else for(var t=-1,n=e.childNodes;++t<n.length;)o.nodeScriptReplace(n[t]);return e},nodeScriptClone:e=>{var t=document.createElement("script");t.text=e.innerHTML;for(var n,o=-1,i=e.attributes;++o<i.length;)t.setAttribute((n=i[o]).name,n.value);return t}};function i(e,t){return e=parseInt(e),t=parseInt(t),isNaN(e)||isNaN(t)?0:(t>e&&(t=Math.round(t/1e3)),Math.round((e-t)/86400))}const s=[],a=(window.pwpSettings?window.pwpSettings.root:"/wp-json/")+"personalizewp/",r=[];let c=!1;const d=Math.round(Date.now()/1e3),l=(new Date).toTimeString(),p={timeOfDay:function(){const e=(new Date).getHours();return e>=0&&e<6?"nighttime":e>=6&&e<12?"morning":e>=12&&e<18?"afternoon":e>=18&&e<=23?"evening":""}(),currentTime:l.substring(0,l.indexOf(" ")),currentTimestamp:(new Date).toISOString(),isReturningVisitor:!0,daysSinceLastVisit:0,deviceType:function(){const e=function(){const e=navigator.userAgent||navigator.vendor||window.opera;return/windows phone/i.test(e)?"windows":/android/i.test(e)?"android":/iPad|iPhone|iPod/.test(e)&&!window.MSStream?"ios":/mac/i.test(e)?"macos":/win/i.test(e)?"windows":/linux/i.test(e)?"linux":""}();return function(){let e=!1;var t;return t=navigator.userAgent||navigator.vendor||window.opera,(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(t)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(t.substr(0,4)))&&(e=!0),e}()?["mobile",e]:function(){const e=navigator.userAgent.toLowerCase();return/(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/.test(e)}()?["tablet",e]:["desktop",e]}(),uid:null!==(n=o.pwpGet("tracked_user",!0,"pwp")?.id)&&void 0!==n?n:""},u=o.pwpGet("first_visit");null===u?(o.pwpStore("first_visit",d),p.isReturningVisitor=!1):u>d?o.pwpStore("first_visit",Math.round(u/1e3)):1>i(d,parseInt(u))&&(p.isReturningVisitor=!1);var w,m=sessionStorage.getItem("personalizewp_last_session");async function g(e,t="v2/blocks"){if(0===e.length)return null;const n={...p,location:location.pathname,blocks:e,urlQueryString:window.location.search+window.location.hash,referrerURL:document.referrer,pageProps:h(window?.PWPTrack||{})},i=await o.callApi(t,n);return i&&i.length?i:null}function h(e){const t=["type","obj"];return Object.keys(e).filter(e=>t.includes(e)).reduce((t,n)=>({...t,[n]:e[n]}),{})}function b(e,t){s.indexOf(t)>=0||(e(),s.push(t))}function f(e,t){window.pwpSettings.delayInit?function(e,t){const n=()=>{b(e,t)},o={once:!0};document.body.addEventListener("mousemove",n,o),document.body.addEventListener("scroll",n,o),document.body.addEventListener("keydown",n,o),document.body.addEventListener("click",n,o),document.body.addEventListener("touchstart",n,o)}(e,t):"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{b(e,t)},{once:!0}):b(e,t)}null===m||isNaN(parseInt(m))?(m=parseInt(null!==(w=o.pwpGet("last_visit"))&&void 0!==w?w:d),sessionStorage.setItem("personalizewp_last_session",m)):parseInt(m)>d&&(m=Math.round(parseInt(m)/1e3),sessionStorage.setItem("personalizewp_last_session",m)),p.daysSinceLastVisit=i(d,m),o.pwpStore("last_visit",d);const v=[];class k extends HTMLElement{connectedCallback(){this.blockId&&(void 0===v[this.delayed]&&(v[this.delayed]={parsing:!1,elements:[]}),v[this.delayed].elements.push(this))}get blockId(){return this.getAttribute("block-id")}get delayed(){let e=this.getAttribute("delayed");return e?Number(e):0}get lifetime(){let e=this.getAttribute("lifetime");return e?Number(e):0}}return window.customElements.define("pwp-block",k),f(function e(){Object.keys(v).forEach(function(t){if(v[t].parsing)return;v[t].parsing=!0;const n=v[t].elements;let i=[];for(let e of n)i.push(e.blockId);i.length?g(i).then(i=>{if(!Array.isArray(i))throw"No blocks to parse";const s=[];i.forEach(function(e){const t=n.shift();e?s.push([t,e]):t.remove()}),s.length&&setTimeout(function(){s.forEach(function(e){const t=e[0].parentNode;let n=document.createElement("div");if(n.innerHTML=e[1],n=o.nodeScriptReplace(n),e[0].lifetime){const t=1e3*e[0].lifetime,o=n.childNodes;for(const e of o)setTimeout(function(){e.remove()},t)}e[0].replaceWith(...n.childNodes);const i=new CustomEvent("PWP:parsePlaceholder",{bubbles:!0,cancelable:!0,detail:{container:t}});t.dispatchEvent(i)}),document.dispatchEvent(new CustomEvent("DOMContentLoaded"));const t=new CustomEvent("PWP:parsedPlaceholders",{bubbles:!0,cancelable:!0});document.dispatchEvent(t),e()},1e3*t),v[t].parsing=!1}).catch(e=>{console.log(e)}):v[t].parsing=!1})},"pwp"),document.addEventListener("DOMContentLoaded",()=>function(){c=!0;for(let e of r)e.ready(this)}(),{once:!0}),t.utils=o,t.getBlocks=g,t.module=function(e,t,n=!1){const o=()=>{t.init&&t.init(),t.ready&&(c?t.ready(this):r.push(t))};n?o():f(o,e)},t.hooks=(0,e.createHooks)(),t}({})})();
     1(()=>{"use strict";const e=window.wp.hooks;window.PersonalizeWP=function(t,n){function o(e){if(!e)return;const t=Math.round(Date.now()/1e3);i.pwpStore("nonce",{nonce:e,timestamp:t})}let i={pwpGet:(e,t=!1,n="personalizewp")=>{const o=localStorage.getItem(`${n}_${e}`);return o?t?JSON.parse(o):o:null},pwpStore:(e,t,n="personalizewp")=>{localStorage.setItem(`${n}_${e}`,JSON.stringify(t))},pwpClear:(e,t="personalizewp")=>{localStorage.removeItem(`${t}_${e}`)},callApi:async(e,t,n=!0)=>{try{const a=await async function(){if(!window.pwpSettings?.isLoggedIn)return null;let{nonce:e,timestamp:t}=function(){const e=i.pwpGet("nonce",!0)||null;return e||i.pwpClear("nonce"),{nonce:e&&e?.nonce||"",timestamp:e&&e?.timestamp||0}}();const n=Math.round(Date.now()/1e3);if(!e||!t||t<n-43200){if(e=await async function(){if(!window.pwpSettings?.nonceEndpoint)return null;try{const e=await fetch(window.pwpSettings?.nonceEndpoint,{mode:"cors",cache:"no-cache",headers:{"Cache-Control":"no-cache","X-Requested-With":"XMLHttpRequest"}});if(!e.ok)throw new Error(`Response status: ${e.status}`);return await e.text()}catch(e){return console.warn("PersonalizeWP: Nonce Error:",e),null}}(),!e)return null;o(e)}return await e}(),s=await fetch(`${r}${e}`,{mode:"cors",method:"POST",cache:"no-cache",headers:{Accept:"application/json, */*;q=0.1","Cache-Control":"no-cache","Content-type":"application/json","X-Requested-With":"XMLHttpRequest",...window.pwpSettings?.apiToken&&{"X-PWP-Auth-Token":window.pwpSettings.apiToken},...a&&{"X-WP-Nonce":a}},body:JSON.stringify(t)});if(!s.ok){if(403===s.status&&a&&n)return i.pwpClear("nonce"),await i.callApi(e,t,!1);throw new Error(`Response status: ${s.status}`)}const c=s.headers.get("X-WP-Nonce");return a!==c&&o(c),await s.json()}catch(e){console.warn("PersonalizeWP: API Error:",e)}return null},nodeScriptReplace:e=>{if("SCRIPT"===e.tagName)e.parentNode.replaceChild(i.nodeScriptClone(e),e);else for(var t=-1,n=e.childNodes;++t<n.length;)i.nodeScriptReplace(n[t]);return e},nodeScriptClone:e=>{var t=document.createElement("script");t.text=e.innerHTML;for(var n,o=-1,i=e.attributes;++o<i.length;)t.setAttribute((n=i[o]).name,n.value);return t}};function a(e,t){return e=parseInt(e),t=parseInt(t),isNaN(e)||isNaN(t)?0:(t>e&&(t=Math.round(t/1e3)),Math.round((e-t)/86400))}const s=[],r=(window.pwpSettings?window.pwpSettings.root:"/wp-json/")+"personalizewp/",c=[];let l=!1;const d=Math.round(Date.now()/1e3),p=(new Date).toTimeString(),u={timeOfDay:function(){const e=(new Date).getHours();return e>=0&&e<6?"nighttime":e>=6&&e<12?"morning":e>=12&&e<18?"afternoon":e>=18&&e<=23?"evening":""}(),currentTime:p.substring(0,p.indexOf(" ")),currentTimestamp:(new Date).toISOString(),isReturningVisitor:!0,daysSinceLastVisit:0,deviceType:function(){const e=function(){const e=navigator.userAgent||navigator.vendor||window.opera;return/windows phone/i.test(e)?"windows":/android/i.test(e)?"android":/iPad|iPhone|iPod/.test(e)&&!window.MSStream?"ios":/mac/i.test(e)?"macos":/win/i.test(e)?"windows":/linux/i.test(e)?"linux":""}();return function(){let e=!1;var t;return t=navigator.userAgent||navigator.vendor||window.opera,(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(t)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(t.substr(0,4)))&&(e=!0),e}()?["mobile",e]:function(){const e=navigator.userAgent.toLowerCase();return/(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/.test(e)}()?["tablet",e]:["desktop",e]}(),uid:null!==(n=i.pwpGet("tracked_user",!0,"pwp")?.id)&&void 0!==n?n:""},w=i.pwpGet("first_visit");null===w?(i.pwpStore("first_visit",d),u.isReturningVisitor=!1):w>d?i.pwpStore("first_visit",Math.round(w/1e3)):1>a(d,parseInt(w))&&(u.isReturningVisitor=!1);var m,h=sessionStorage.getItem("personalizewp_last_session");async function g(e,t="v2/blocks"){if(0===e.length)return null;const n={...u,location:location.pathname,blocks:e,urlQueryString:window.location.search+window.location.hash,referrerURL:document.referrer,pageProps:f(window?.PWPTrack||{})},o=await i.callApi(t,n);return o&&o.length?o:null}function f(e){const t=["type","obj"];return Object.keys(e).filter(e=>t.includes(e)).reduce((t,n)=>({...t,[n]:e[n]}),{})}function b(e,t){s.indexOf(t)>=0||(e(),s.push(t))}function v(e,t){window.pwpSettings.delayInit?function(e,t){const n=()=>{b(e,t)},o={once:!0};document.body.addEventListener("mousemove",n,o),document.body.addEventListener("scroll",n,o),document.body.addEventListener("keydown",n,o),document.body.addEventListener("click",n,o),document.body.addEventListener("touchstart",n,o)}(e,t):"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{b(e,t)},{once:!0}):b(e,t)}null===h||isNaN(parseInt(h))?(h=parseInt(null!==(m=i.pwpGet("last_visit"))&&void 0!==m?m:d),sessionStorage.setItem("personalizewp_last_session",h)):parseInt(h)>d&&(h=Math.round(parseInt(h)/1e3),sessionStorage.setItem("personalizewp_last_session",h)),u.daysSinceLastVisit=a(d,h),i.pwpStore("last_visit",d);const k=[];class y extends HTMLElement{connectedCallback(){this.blockId&&(void 0===k[this.delayed]&&(k[this.delayed]={parsing:!1,elements:[]}),k[this.delayed].elements.push(this))}get blockId(){return this.getAttribute("block-id")}get delayed(){let e=this.getAttribute("delayed");return e?Number(e):0}get lifetime(){let e=this.getAttribute("lifetime");return e?Number(e):0}}return window.customElements.define("pwp-block",y),v(function e(){Object.keys(k).forEach(function(t){if(k[t].parsing)return;k[t].parsing=!0;const n=k[t].elements;let o=[];for(let e of n)o.push(e.blockId);o.length?g(o).then(o=>{if(!Array.isArray(o))throw"No blocks to parse";const a=[];o.forEach(function(e){const t=n.shift();e?a.push([t,e]):t.remove()}),a.length&&setTimeout(function(){a.forEach(function(e){const t=e[0].parentNode;let n=document.createElement("div");if(n.innerHTML=e[1],n=i.nodeScriptReplace(n),e[0].lifetime){const t=1e3*e[0].lifetime,o=n.childNodes;for(const e of o)setTimeout(function(){e.remove()},t)}e[0].replaceWith(...n.childNodes);const o=new CustomEvent("PWP:parsePlaceholder",{bubbles:!0,cancelable:!0,detail:{container:t}});t.dispatchEvent(o)}),document.dispatchEvent(new CustomEvent("DOMContentLoaded"));const t=new CustomEvent("PWP:parsedPlaceholders",{bubbles:!0,cancelable:!0});document.dispatchEvent(t),e()},1e3*t),k[t].parsing=!1}).catch(e=>{console.log(e)}):k[t].parsing=!1})},"pwp"),document.addEventListener("DOMContentLoaded",()=>function(){l=!0;for(let e of c)e.ready(this)}(),{once:!0}),t.utils=i,t.getBlocks=g,t.module=function(e,t,n=!1){const o=()=>{t.init&&t.init(),t.ready&&(l?t.ready(this):c.push(t))};n?o():v(o,e)},t.hooks=(0,e.createHooks)(),t}({})})();
  • personalizewp/trunk/src/public/js/pwp.js

    r3452048 r3458877  
    44window.PersonalizeWP = (function (exports) {
    55    "use strict";
     6
     7    /**
     8     * Returns the local storage of the users nonce and its TTL.
     9     * @returns {object}
     10     */
     11    function getStoredUserNonce() {
     12        const userNonce = utils.pwpGet('nonce', true) || null;
     13        if ( ! userNonce ) {
     14            // Clear in case of bad data.
     15            utils.pwpClear('nonce');
     16        }
     17        // Validate stored nonce, revert to defaults otherwise
     18        const data = {
     19            nonce: (userNonce && userNonce?.nonce ) || '',
     20            timestamp: (userNonce && userNonce?.timestamp) || 0,
     21        };
     22        return data;
     23    }
     24
     25    /**
     26     * Store an updated nonce, refreshing its TTL to now.
     27     * @param {string} nonce
     28     */
     29    function storeUserNonce( nonce ) {
     30        if ( ! nonce ) return;
     31        const now = Math.round(Date.now() / 1000); // Now in seconds
     32
     33        // Store the updated nonce.
     34        utils.pwpStore( 'nonce', { nonce, timestamp: now } );
     35    }
     36
     37    /**
     38     * Returns a new CSRF nonce for the current user.
     39     * @returns {string | null}
     40     */
     41    async function refreshUserNonce() {
     42        // Without an endpoint, can never get a user nonce.
     43        if (! window.pwpSettings?.nonceEndpoint) {
     44            return null;
     45        }
     46        try {
     47            const response = await fetch(window.pwpSettings?.nonceEndpoint, {
     48                mode:  'cors', // Assume cross-origin
     49                cache: 'no-cache',
     50                headers: {
     51                    'Cache-Control': 'no-cache',
     52                    'X-Requested-With': 'XMLHttpRequest',
     53                }
     54            });
     55            if (!response.ok) {
     56                throw new Error(`Response status: ${response.status}`);
     57            }
     58            // New nonce generated.
     59            return await response.text();
     60        } catch( error ) {
     61            console.warn('PersonalizeWP: Nonce Error:', error);
     62            return null;
     63        }
     64        return null;
     65    }
     66
     67    /**
     68     * Checks for a stored user nonce, refreshes if needed, before returning.
     69     * @returns {string | null}
     70     */
     71    async function getUserNonce() {
     72        if ( ! window.pwpSettings?.isLoggedIn ) {
     73            return null;
     74        }
     75        // Get the stored nonce
     76        let { nonce, timestamp } = getStoredUserNonce();
     77        const now = Math.round(Date.now() / 1000); // Now in seconds
     78        // TTL for nonce is 12 hrs.
     79        if ( ! nonce || ! timestamp || timestamp < ( now - ( 60 * 60 * 12 ) ) ) {
     80            // Refresh the nonce and its TTL
     81            nonce = await refreshUserNonce(); // MUST wait for the nonce to resolve.
     82            if ( ! nonce ) {
     83                // Console already warned in refreshUserNonce()
     84                return null;
     85            }
     86            // Store the updated nonce.
     87            storeUserNonce( nonce );
     88        }
     89        return await nonce;
     90    }
    691
    792    /**
     
    44129
    45130        /**
    46          * Call a PWP request api
    47          * @param {String} u The url of the endpoint
    48          * @param {String} b The parameter body
     131         * Make a PersonalizeWP API request
     132         * @param {String} url The url of the endpoint
     133         * @param {String} body The parameter body
     134         * @param {Boolean} retry Should the request retry after the first failure. Default true when using nonces
    49135         * @return {Promise<any | null>} The response body of request
    50136         */
    51         callApi: async (u, b) => {
     137        callApi: async (url, body, retry = true) => {
    52138            try {
    53                 // const loc = document.location;
    54                 const response = await fetch(`${baseUrl}${u}`, {
     139                const userNonce = await getUserNonce(); // MUST wait for the nonce to complete.
     140                const response = await fetch(`${baseUrl}${url}`, {
    55141                    mode:  'cors', // Assume cross-origin
    56142                    method: 'POST', // Generally not 'creating' content, but POST allows a larger quantity of params via the body
     
    61147                        'Content-type': 'application/json',
    62148                        'X-Requested-With': 'XMLHttpRequest',
    63                         ...(window.pwpSettings &&
    64                             // Safely check for auth token
    65                             window.pwpSettings.apiToken && {
     149                        // Safely check and include auth token
     150                        ...(window.pwpSettings?.apiToken && {
    66151                                'X-PWP-Auth-Token': window.pwpSettings.apiToken,
    67152                            }),
    68                         ...(window.pwpSettings &&
    69                             // Safely check for nonce
    70                             window.pwpSettings.nonce && {
    71                                 'X-WP-Nonce': window.pwpSettings.nonce,
    72                             }),
     153                        // Safely check and include a logged in user nonce
     154                        ...(userNonce && {
     155                            'X-WP-Nonce': userNonce
     156                        }),
    73157                    },
    74                     body: JSON.stringify(b),
     158                    body: JSON.stringify(body),
    75159                });
    76160                if (!response.ok) {
     161                    if ( 403 === response.status && userNonce && retry ) {
     162                        // Possible corruption of the existing nonce, clear storage and try again.
     163                        utils.pwpClear('nonce');
     164
     165                        // Ensure we only try one more time. No infinite loops.
     166                        return await utils.callApi( url, body, false );
     167                    }
    77168                    throw new Error(`Response status: ${response.status}`);
     169                }
     170                // Update the users nonce when a new nonce is returned with the response.
     171                const returnedNonce = response.headers.get('X-WP-Nonce');
     172                if ( userNonce !== returnedNonce ) {
     173                    storeUserNonce( returnedNonce );
    78174                }
    79175                return await response.json();
    80176            } catch (error) {
    81                 console.warn('API Error:', error);
     177                console.warn('PersonalizeWP: API Error:', error);
    82178            }
    83179            return null;
Note: See TracChangeset for help on using the changeset viewer.