Plugin Directory

Changeset 3730683


Ignore:
Timestamp:
10/06/2026 11:38:26 AM (3 weeks ago)
Author:
gturtle108
Message:

Release 1.240.1: a co-parent's card never goes on the household payer's account

Location:
gather-grove-booking/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • gather-grove-booking/trunk/gather-grove-booking.php

    r3730543 r3730683  
    44 * Plugin URI:  https://gathergrove.io/docs/booking
    55 * Description: Class scheduling and booking for studios, wellness centers, and community programs.
    6  * Version:     1.240.0
     6 * Version:     1.240.1
    77 * Author:      Rob Hewitt / Gather Grove
    88 * Author URI:  https://gathergrove.io
    … …  
    2121defined( 'ABSPATH' ) || exit;
    2222
    23 define( 'GATHER_GROVE_VERSION',          '1.240.0' );
     23define( 'GATHER_GROVE_VERSION',          '1.240.1' );
    2424// Bump this whenever any CPT/taxonomy/rewrite registration changes — every
    2525// install will flush its rule cache on next admin page load. Existing studios
  • gather-grove-booking/trunk/languages/gather-grove-booking.pot

    r3730543 r3730683  
    33msgid ""
    44msgstr ""
    5 "Project-Id-Version: Gather Grove Booking 1.240.0\n"
     5"Project-Id-Version: Gather Grove Booking 1.240.1\n"
    66"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/gather-grove-booking\n"
    77"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
    … …  
    1010"Content-Type: text/plain; charset=UTF-8\n"
    1111"Content-Transfer-Encoding: 8bit\n"
    12 "POT-Creation-Date: 2026-10-06T10:36:37+00:00\n"
     12"POT-Creation-Date: 2026-10-06T11:36:08+00:00\n"
    1313"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
    1414"X-Generator: WP-CLI 2.12.0\n"
    … …  
    49114911#: src/Elementor/Widgets/BookingFormWidget.php:2264
    49124912#: src/Services/AddSeats.php:326
    4913 #: src/Services/ClientService.php:2334
     4913#: src/Services/ClientService.php:2374
    49144914msgid "Each guest needs a name."
    49154915msgstr ""
    … …  
    50635063#: src/Admin/Pages/ClientsPage.php:279
    50645064#: src/Admin/Pages/ClientsPage.php:4341
    5065 #: src/Services/ClientService.php:3865
     5065#: src/Services/ClientService.php:3905
    50665066msgid "Family & Household Accounts is not enabled on this site."
    50675067msgstr ""
    … …  
    2642326423msgstr ""
    2642426424
    26425 #: src/Services/ClientService.php:2217
     26425#: src/Services/ClientService.php:2257
    2642626426msgid "A household member needs a name and a valid payer."
    2642726427msgstr ""
    2642826428
    26429 #: src/Services/ClientService.php:2226
    26430 #: src/Services/ClientService.php:2442
    26431 #: src/Services/ClientService.php:3437
     26429#: src/Services/ClientService.php:2266
     26430#: src/Services/ClientService.php:2482
     26431#: src/Services/ClientService.php:3477
    2643226432msgid "The household payer could not be found."
    2643326433msgstr ""
    2643426434
    26435 #: src/Services/ClientService.php:2234
     26435#: src/Services/ClientService.php:2274
    2643626436msgid "A household member cannot manage their own members."
    2643726437msgstr ""
    2643826438
    26439 #: src/Services/ClientService.php:2288
     26439#: src/Services/ClientService.php:2328
    2644026440msgid "The household member could not be created. Please try again."
    2644126441msgstr ""
    2644226442
    26443 #: src/Services/ClientService.php:2387
     26443#: src/Services/ClientService.php:2427
    2644426444msgid "The guest could not be added. Please try again."
    2644526445msgstr ""
    2644626446
    26447 #: src/Services/ClientService.php:2433
     26447#: src/Services/ClientService.php:2473
    2644826448msgid "A valid payer and the member’s email are required."
    2644926449msgstr ""
    2645026450
    26451 #: src/Services/ClientService.php:2449
     26451#: src/Services/ClientService.php:2489
    2645226452msgid "A household member cannot manage other members."
    2645326453msgstr ""
    2645426454
    26455 #: src/Services/ClientService.php:2459
     26455#: src/Services/ClientService.php:2499
    2645626456msgid "No account exists for that email yet. Send them an invitation instead — they can create an account and join your household from the link in the email."
    2645726457msgstr ""
    2645826458
    26459 #: src/Services/ClientService.php:2468
     26459#: src/Services/ClientService.php:2508
    2646026460msgid "That account could not be linked. Please try again."
    2646126461msgstr ""
    2646226462
    26463 #: src/Services/ClientService.php:2496
     26463#: src/Services/ClientService.php:2536
    2646426464msgid "You cannot add yourself as a household member."
    2646526465msgstr ""
    2646626466
    26467 #: src/Services/ClientService.php:2513
    26468 #: src/Services/ClientService.php:3482
     26467#: src/Services/ClientService.php:2553
     26468#: src/Services/ClientService.php:3522
    2646926469msgid "That person already belongs to another household."
    2647026470msgstr ""
    2647126471
    26472 #: src/Services/ClientService.php:2527
     26472#: src/Services/ClientService.php:2567
    2647326473msgid "That person manages their own household and cannot be linked as a member."
    2647426474msgstr ""
    2647526475
    26476 #: src/Services/ClientService.php:2566
     26476#: src/Services/ClientService.php:2606
    2647726477msgid "Linking the member failed. Please try again."
    2647826478msgstr ""
    2647926479
    26480 #: src/Services/ClientService.php:2655
     26480#: src/Services/ClientService.php:2695
    2648126481msgid "this person"
    2648226482msgstr ""
    2648326483
    2648426484#. translators: 1: household member's name, 2: the studio with its determiner (e.g. "the studio")
    26485 #: src/Services/ClientService.php:2659
     26485#: src/Services/ClientService.php:2699
    2648626486#, php-format
    2648726487msgid "Add %1$s's birthday so you can book and pay for them. Ask %2$s to add it: %1$s has their own login, so only %2$s can change their details."
    2648826488msgstr ""
    2648926489
    26490 #: src/Services/ClientService.php:2727
    26491 #: src/Services/ClientService.php:2797
    26492 #: src/Services/ClientService.php:2816
    26493 #: src/Services/ClientService.php:2934
    26494 #: src/Services/ClientService.php:3079
    26495 #: src/Services/ClientService.php:3145
    26496 #: src/Services/ClientService.php:3259
     26490#: src/Services/ClientService.php:2767
     26491#: src/Services/ClientService.php:2837
     26492#: src/Services/ClientService.php:2856
     26493#: src/Services/ClientService.php:2974
     26494#: src/Services/ClientService.php:3119
     26495#: src/Services/ClientService.php:3185
     26496#: src/Services/ClientService.php:3299
    2649726497msgid "That person is not a member of this household."
    2649826498msgstr ""
    2649926499
    26500 #: src/Services/ClientService.php:2755
     26500#: src/Services/ClientService.php:2795
    2650126501msgid "Removing the member failed. Please try again."
    2650226502msgstr ""
    2650326503
    26504 #: src/Services/ClientService.php:2824
     26504#: src/Services/ClientService.php:2864
    2650526505msgid "Only a household member with their own login can manage others. Invite them to create an account first."
    2650626506msgstr ""
    2650726507
    26508 #: src/Services/ClientService.php:2839
     26508#: src/Services/ClientService.php:2879
    2650926509msgid "This person is set up as someone the household books for. Turn that off first if they should manage others instead."
    2651026510msgstr ""
    2651126511
    26512 #: src/Services/ClientService.php:2854
    26513 #: src/Services/ClientService.php:2993
    26514 #: src/Services/ClientService.php:3094
     26512#: src/Services/ClientService.php:2894
     26513#: src/Services/ClientService.php:3033
     26514#: src/Services/ClientService.php:3134
    2651526515msgid "That change could not be saved. Please try again."
    2651626516msgstr ""
    2651726517
    2651826518#. translators: %s: the studio with its determiner (e.g. "the studio"), or its name alone when the studio is a name (e.g. "Alana")
    26519 #: src/Services/ClientService.php:2945
     26519#: src/Services/ClientService.php:2985
    2652026520#, php-format
    2652126521msgid "Only this person or %s can change who books for them."
    2652226522msgstr ""
    2652326523
    26524 #: src/Services/ClientService.php:2961
     26524#: src/Services/ClientService.php:3001
    2652526525msgid "You need to be part of a household before someone can book for you."
    2652626526msgstr ""
    2652726527
    26528 #: src/Services/ClientService.php:2969
     26528#: src/Services/ClientService.php:3009
    2652926529msgid "This person has no login of their own, so the household already books for them."
    2653026530msgstr ""
    2653126531
    26532 #: src/Services/ClientService.php:2978
     26532#: src/Services/ClientService.php:3018
    2653326533msgid "This person manages others in the household. Remove that first if the household should book for them instead."
    2653426534msgstr ""
    2653526535
    26536 #: src/Services/ClientService.php:3137
    26537 #: src/Services/ClientService.php:3291
     26536#: src/Services/ClientService.php:3177
     26537#: src/Services/ClientService.php:3331
    2653826538msgid "A name is required."
    2653926539msgstr ""
    2654026540
    26541 #: src/Services/ClientService.php:3155
     26541#: src/Services/ClientService.php:3195
    2654226542msgid "This member has their own account and manages their own name."
    2654326543msgstr ""
    2654426544
    26545 #: src/Services/ClientService.php:3172
     26545#: src/Services/ClientService.php:3212
    2654626546msgid "Renaming the member failed. Please try again."
    2654726547msgstr ""
    2654826548
    26549 #: src/Services/ClientService.php:3269
     26549#: src/Services/ClientService.php:3309
    2655026550msgid "This member has their own account and manages their own details."
    2655126551msgstr ""
    2655226552
    26553 #: src/Services/ClientService.php:3309
     26553#: src/Services/ClientService.php:3349
    2655426554msgid "Please enter the date of birth as YYYY-MM-DD."
    2655526555msgstr ""
    2655626556
    26557 #: src/Services/ClientService.php:3318
     26557#: src/Services/ClientService.php:3358
    2655826558msgid "That date is in the future — please check it."
    2655926559msgstr ""
    2656026560
    26561 #: src/Services/ClientService.php:3337
     26561#: src/Services/ClientService.php:3377
    2656226562msgid "No details were supplied to change."
    2656326563msgstr ""
    2656426564
    26565 #: src/Services/ClientService.php:3355
     26565#: src/Services/ClientService.php:3395
    2656626566msgid "Saving those details failed. Please try again."
    2656726567msgstr ""
    2656826568
    26569 #: src/Services/ClientService.php:3428
     26569#: src/Services/ClientService.php:3468
    2657026570msgid "A valid payer and the adult’s email are required."
    2657126571msgstr ""
    2657226572
    26573 #: src/Services/ClientService.php:3445
     26573#: src/Services/ClientService.php:3485
    2657426574msgid "A household member cannot invite other members."
    2657526575msgstr ""
    2657626576
    26577 #: src/Services/ClientService.php:3453
    26578 #: src/Services/ClientService.php:3467
     26577#: src/Services/ClientService.php:3493
     26578#: src/Services/ClientService.php:3507
    2657926579msgid "You cannot invite yourself to your own household."
    2658026580msgstr ""
    2658126581
    26582 #: src/Services/ClientService.php:3475
     26582#: src/Services/ClientService.php:3515
    2658326583msgid "That person is already a member of your household."
    2658426584msgstr ""
    2658526585
    26586 #: src/Services/ClientService.php:3494
     26586#: src/Services/ClientService.php:3534
    2658726587msgid "That person manages their own household and cannot be invited as a member."
    2658826588msgstr ""
    2658926589
    26590 #: src/Services/ClientService.php:3534
     26590#: src/Services/ClientService.php:3574
    2659126591msgid "The invitation could not be created. Please try again."
    2659226592msgstr ""
    2659326593
    26594 #: src/Services/ClientService.php:3713
    26595 #: src/Services/ClientService.php:3744
     26594#: src/Services/ClientService.php:3753
     26595#: src/Services/ClientService.php:3784
    2659626596msgid "That invitation could not be found."
    2659726597msgstr ""
    2659826598
    26599 #: src/Services/ClientService.php:3720
     26599#: src/Services/ClientService.php:3760
    2660026600msgid "That invitation can no longer be cancelled."
    2660126601msgstr ""
    2660226602
    26603 #: src/Services/ClientService.php:3751
     26603#: src/Services/ClientService.php:3791
    2660426604msgid "That invitation is no longer active. Send a new one instead."
    2660526605msgstr ""
  • gather-grove-booking/trunk/readme.txt

    r3730543 r3730683  
    55Tested up to: 7.1
    66Requires PHP: 8.2
    7 Stable tag: 1.240.0
     7Stable tag: 1.240.1
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    147147== Changelog ==
    148148
     149= 1.240.1 =
     150* Security: when a co-parent signed a child up for a membership, their card was saved on the paying parent's account, where the paying parent could use it. A co-parent now pays for a membership they start from their own account, with their own card, and gets its invoices, receipts and reminders. Studios using co-parents should run `wp gather-grove billing cards --list`, then `--tag --yes`.
     151* Fix: the person who pays for a household member's membership can now cancel it from their account page (they got "Membership not found").
     152* New (developers): `wp gather-grove billing cards` lists memberships a co-parent started before 1.240.1 and tags the co-parent's card as theirs.
     153
    149154= 1.240.0 =
    150155* New: Settings, Payments, "Bill children with their own login to the household payer", on by default. When a parent starts a membership for a child in their household, it is billed to the parent's account and the invoices come to the parent, whether or not the child has a login. A child who signs up themselves still pays for it. Memberships already running don't move.
  • gather-grove-booking/trunk/src/Services/ClientService.php

    r3730543 r3730683  
    14901490         * charge lands on an account whose owner is not there to agree to it.
    14911491         * Buying for someone else in your household, the resolver decides.
     1492         *
     1493         * 🔑 **A co-parent pays for what they start (1.240.1, Booking rule 192).**
     1494         * When the resolver names the household payer but the buyer is a
     1495         * household MANAGER acting for a member they manage, the manager pays,
     1496         * from their own Stripe customer. Before 1.240.1 the manager's card went
     1497         * onto the household payer's customer, untagged, as that customer's
     1498         * default — one person's card on another person's customer, which rule
     1499         * 192 forbids, and a charge on the account of someone who was not there
     1500         * to agree to it (spec §4.1). The membership still belongs to the
     1501         * member (rule 41); only who pays changes.
    14921502         */
    14931503        public static function checkout_membership_payer( int $buyer_client_id, int $subject_client_id ): int {
    … …  
    14961506                }
    14971507
    1498                 return self::membership_payer_client_id( $subject_client_id );
     1508                $resolved = self::membership_payer_client_id( $subject_client_id );
     1509
     1510                if ( $resolved > 0
     1511                        && $resolved !== $buyer_client_id
     1512                        && $resolved !== $subject_client_id
     1513                        && self::is_coparent_of( $buyer_client_id, $subject_client_id )
     1514                ) {
     1515                        return $buyer_client_id;
     1516                }
     1517
     1518                return $resolved;
     1519        }
     1520
     1521        /**
     1522         * Is `$manager_client_id` a co-parent of `$member_client_id` — a
     1523         * designated household manager (Co-Parent Flow, 1.121.0) of the member's
     1524         * household who may act for them (`can_manage()`)? Never true of the
     1525         * household payer or of the member themselves.
     1526         */
     1527        public static function is_coparent_of( int $manager_client_id, int $member_client_id ): bool {
     1528                if ( $manager_client_id <= 0 || $member_client_id <= 0 || $manager_client_id === $member_client_id ) {
     1529                        return false;
     1530                }
     1531
     1532                return self::is_household_manager( $manager_client_id )
     1533                        && self::can_manage( $manager_client_id, $member_client_id );
    14991534        }
    15001535
    15011536        /**
    15021537         * May `$payer_client_id` be recorded as the payer of a membership held by
    1503          * `$member_client_id`? Only the member themselves or their household
    1504          * payer (spec §4.1) — the guard `purchase_membership()` applies to an
    1505          * explicit payer, so no caller can bill a third person's customer.
     1538         * `$member_client_id`? The member themselves, their household payer
     1539         * (spec §4.1), or — from 1.240.1 — a co-parent who manages them and is
     1540         * paying for it from their own account (`is_coparent_of()`). The guard
     1541         * `purchase_membership()` applies to an explicit payer, so no caller can
     1542         * bill a third person's customer.
    15061543         */
    15071544        public static function may_pay_for_membership( int $payer_client_id, int $member_client_id ): bool {
    … …  
    15111548
    15121549                return $payer_client_id === $member_client_id
    1513                         || $payer_client_id === self::household_payer_client_id( $member_client_id );
     1550                        || $payer_client_id === self::household_payer_client_id( $member_client_id )
     1551                        || self::is_coparent_of( $payer_client_id, $member_client_id );
    15141552        }
    15151553
    … …  
    15441582         * passes, and the member, who is not charged, does not.
    15451583         *
    1546          * A household manager is never the payer, so is never let through
    1547          * (Co-Parent Flow, Rob 2026-08-16).
     1584         * A household manager is not the payer of the household's memberships
     1585         * (Co-Parent Flow, Rob 2026-08-16), so is not let through — except for a
     1586         * membership they started and pay for from their own account (1.240.1,
     1587         * rule 192), whose row records them as its payer.
    15481588         */
    15491589        public static function pays_for_membership( int $actor_client_id, object $cp ): bool {
  • gather-grove-booking/trunk/vendor/composer/installed.php

    r3730543 r3730683  
    33  array (
    44    'name' => 'golden-turtle-sound/gather-grove',
    5     'pretty_version' => 'v1.240.0',
    6     'version' => '1.240.0.0',
    7     'reference' => '70f10cabbfdece5f21604bb63bf5e60f113189d8',
     5    'pretty_version' => 'v1.240.1',
     6    'version' => '1.240.1.0',
     7    'reference' => 'a60014b09efeafaf47fd6dc9b8c595ccd0d20272',
    88    'type' => 'wordpress-plugin',
    9     'install_path' => '/private/var/folders/_z/v6yvnpmx5mz91tk62d72jhyc0000gn/T/tmp.wmxOCeBOzO/gather-grove-booking/vendor/composer/../../',
     9    'install_path' => '/private/var/folders/_z/v6yvnpmx5mz91tk62d72jhyc0000gn/T/tmp.H6aDmoqzf7/gather-grove-booking/vendor/composer/../../',
    1010    'aliases' =>
    1111    array (
    … …  
    1717    'golden-turtle-sound/gather-grove' =>
    1818    array (
    19       'pretty_version' => 'v1.240.0',
    20       'version' => '1.240.0.0',
    21       'reference' => '70f10cabbfdece5f21604bb63bf5e60f113189d8',
     19      'pretty_version' => 'v1.240.1',
     20      'version' => '1.240.1.0',
     21      'reference' => 'a60014b09efeafaf47fd6dc9b8c595ccd0d20272',
    2222      'type' => 'wordpress-plugin',
    23       'install_path' => '/private/var/folders/_z/v6yvnpmx5mz91tk62d72jhyc0000gn/T/tmp.wmxOCeBOzO/gather-grove-booking/vendor/composer/../../',
     23      'install_path' => '/private/var/folders/_z/v6yvnpmx5mz91tk62d72jhyc0000gn/T/tmp.H6aDmoqzf7/gather-grove-booking/vendor/composer/../../',
    2424      'aliases' =>
    2525      array (
    … …  
    3333      'reference' => 'fe99159b9ee0a74be3c12c0305e5338e0b9905c3',
    3434      'type' => 'library',
    35       'install_path' => '/private/var/folders/_z/v6yvnpmx5mz91tk62d72jhyc0000gn/T/tmp.wmxOCeBOzO/gather-grove-booking/vendor/composer/../stripe/stripe-php',
     35      'install_path' => '/private/var/folders/_z/v6yvnpmx5mz91tk62d72jhyc0000gn/T/tmp.H6aDmoqzf7/gather-grove-booking/vendor/composer/../stripe/stripe-php',
    3636      'aliases' =>
    3737      array (
Note: See TracChangeset for help on using the changeset viewer.