Plugin Directory

Changeset 3332990


Ignore:
Timestamp:
07/23/2025 02:12:33 PM (7 months ago)
Author:
givewp
Message:

Update to version 2.1.0 from GitHub

Location:
give-double-the-donation
Files:
8 added
2 deleted
30 edited
1 copied

Legend:

Unmodified
Added
Removed
  • give-double-the-donation/tags/2.1.0/build/frontend.asset.php

    r3072620 r3332990  
    1 <?php return array('dependencies' => array(), 'version' => '95b1e6ad157050134353');
     1<?php return array('dependencies' => array(), 'version' => 'cb2ce59061ec431a0631');
  • give-double-the-donation/tags/2.1.0/build/frontend.js

    r3072620 r3332990  
    1 (()=>{if(window.doublethedonation){function e(){document.querySelectorAll(".dd-company-name-input").forEach((e=>{e.hasAttribute("data-doublethedonation-widget-id")||window.doublethedonation.plugin.load_streamlined_input(e)}))}document.addEventListener("give_gateway_loaded",e),e()}})();
     1(()=>{if(window.doublethedonation){function e(){document.querySelectorAll(".dd-company-name-input").forEach((e=>{e.hasAttribute("data-doublethedonation-widget-id")||(window.doublethedonation.plugin.load_streamlined_input(e),e.addEventListener("change",(()=>{const t=e.dataset.donationId,n=e.dataset.receiptId;window.setTimeout((async()=>{const e=document.querySelector('[name="doublethedonation_company_id"]').value,o=document.querySelector('[name="doublethedonation_company_name"]').value,d=document.querySelector('[name="doublethedonation_entered_text"]').value;await fetch(DDCONF.GIVE_ENDPOINT+t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({companyId:e,companyName:o,enteredText:d,receiptId:n})}),document.querySelectorAll(".wrongcompany a")?.forEach((e=>{e.addEventListener("click",(()=>{fetch(DDCONF.GIVE_ENDPOINT+t+`?receiptId=${n}`,{method:"DELETE"})}))}))}),500)})))}))}document.addEventListener("give_gateway_loaded",e),document.addEventListener("DOMContentLoaded",e)}})();
  • give-double-the-donation/tags/2.1.0/changelog.txt

    r3207135 r3332990  
    11*** Give - Double the Donation changelog ***
     2
     32025-07-23 - version 2.1.0
     4- New: Added compatibility with recurring donations
     5- New: Added additional company match field to the donation confirmation page
    26
    372024-12-12 - version 2.0.2
  • give-double-the-donation/tags/2.1.0/give-double-the-donation.php

    r3207135 r3332990  
    44 * Plugin URI:  https://givewp.com/addons/give-double-the-donation/
    55 * Description: Easily integrate with the Double the Donation employer matching platform.
    6  * Version:     2.0.2
     6 * Version:     2.1.0
    77 * Author:      GiveWP
    8  * Requires at least: 6.3
     8 * Requires at least: 6.6
    99 * Requires PHP: 7.2
    1010 * Author URI:  https://givewp.com/
     
    2626
    2727// Versions
    28 define( 'GIVE_DTD_VERSION', '2.0.2' );
     28define( 'GIVE_DTD_VERSION', '2.1.0' );
    2929define( 'GIVE_DTD_MIN_GIVE_VERSION', '3.8.0' );
    3030
  • give-double-the-donation/tags/2.1.0/readme.txt

    r3207135 r3332990  
    33Donate link: https://givewp.com/
    44Tags: givewp, double the donation, employer matching, company matching donation, employer matching donations
    5 Requires at least: 6.3
    6 Tested up to: 6.7
     5Requires at least: 6.6
     6Tested up to: 6.8
    77Requires PHP: 7.2
    8 Stable tag: 2.0.2
     8Stable tag: 2.1.0
    99Requires Give: 3.8.0
    1010License: GPLv3
     
    1717Empower your GiveWP donors to have their company match their donations with the most powerful Company Matching platform: Double the Donation.
    1818
    19 With this GiveWP add-on, simply add your Double the Donation API keys into the settings, then each of your forms can be enabled to accept company matching. 
     19With this GiveWP add-on, simply add your Double the Donation API keys into the settings, then each of your forms can be enabled to accept company matching.
    2020
    2121**ABOUT DOUBLE THE DONATION:**
    22 Automate your matching gift fundraising with the industry-leading solution from Double the Donation. Double the Donation provides nonprofits with tools to identify match-eligible donors, drive matches to completion, and gain actionable insights. Our unique integration with GiveWP integrates directly into your donation forms, to capture employment information and follow up appropriately with donors about matching gifts. 
     22Automate your matching gift fundraising with the industry-leading solution from Double the Donation. Double the Donation provides nonprofits with tools to identify match-eligible donors, drive matches to completion, and gain actionable insights. Our unique integration with GiveWP integrates directly into your donation forms, to capture employment information and follow up appropriately with donors about matching gifts.
    2323
    2424**ABOUT OUR FREE ADD-ONS**
     
    3131= Minimum Requirements =
    3232
    33 * An active subscription to Double the Donation. 
    34 * WordPress 6.3 or greater
     33* An active subscription to Double the Donation.
     34* WordPress 6.6 or greater
    3535* PHP version 7.2 or greater
    3636* MySQL version 5.7 or greater
     
    5858The companies listed in the Double the Donation dropdown all registered with Double the Donation to provide their employees this opportunity. If your company does not appear there, then most likely they have not yet applied with Double the Donation. You can submit on their behalf, or [send them here to apply](https://doublethedonation.com/matching-gift-database/new-companies-with-matching-gift-programs/).
    5959
    60 = I set my company to match, what happens next? = 
     60= I set my company to match, what happens next? =
    6161Your company will get an email and you will as well with next steps to follow. If you have any trouble with this process, contact [Double the Donation directly here](https://support.doublethedonation.com/portal/en/home).
    6262
    63 == Screenshots == 
     63== Screenshots ==
    6464
    65 1. The company search is powered by Double the Donation. It's fast and intuitive for your donors. 
     651. The company search is powered by Double the Donation. It's fast and intuitive for your donors.
    6666
    67672. Integrating Double the Donation with GiveWP is as simple as inserting your API keys in the settings fields.
     
    7070
    7171== Changelog ==
     72
     73= 2.1.0: July 23rd, 2025 =
     74* New: Added compatibility with recurring donations
     75* New: Added additional company match field to the donation confirmation page
    7276
    7377= 2.0.2: December 12th, 2024 =
  • give-double-the-donation/tags/2.1.0/src/DoubleTheDonation/AddonServiceProvider.php

    r3207135 r3332990  
    33namespace GiveDoubleTheDonation\DoubleTheDonation;
    44
     5use Give\Donations\Models\Donation;
    56use Give\Helpers\Hooks;
    67use Give\ServiceProviders\ServiceProvider;
     
    1011use GiveDoubleTheDonation\Addon\License;
    1112use GiveDoubleTheDonation\DoubleTheDonation\Actions\CheckCredentials;
     13use GiveDoubleTheDonation\DoubleTheDonation\API\REST\CompanyMatching;
    1214use GiveDoubleTheDonation\DoubleTheDonation\Helpers\SettingsPage as SettingsPageRegister;
    1315
     
    3840        Hooks::addAction('give_donation_form_after_email', DonationForm::class, 'employerMatchField');
    3941
    40         // handle v2 forms stuff
    41         if (isset($_POST) && ! isset($_POST['dtd'])) {
    42             Hooks::addAction('give_insert_payment', Payment::class, 'addPaymentMeta', 10, 2);
    43             Hooks::addAction('give_insert_payment', Payment::class, 'addDonationToDTD', 11, 2);
    44         }
     42        add_action('give_insert_payment', function($payment_id, $payment_data) {
     43            // handle for v2 forms (v3 forms uses field scope)
     44            if (isset($_POST) && !isset($_POST['dtd'])) {
     45                give(Payment::class)->addPaymentMeta($payment_id, $payment_data);
     46
     47                $donation = Donation::find((int)$payment_id);
     48
     49                // handle for single donations only
     50                if ($donation->type->isSingle()) {
     51                    give(Payment::class)->addDonationToDTD($payment_id, $payment_data);
     52                }
     53            }
     54        });
     55
     56        /**
     57         * @since 2.1.0 add support for recurring donations
     58         */
     59        Hooks::addAction('give_recurring_record_payment', Payment::class, 'addDonationToDTD', 10, 2);
    4560
    4661        // Show Receipt info
     
    89104    private function loadFrontend()
    90105    {
     106        // @since 2.1.0
     107        Hooks::addAction('rest_api_init', CompanyMatching::class);
     108
    91109        // Load front-end assets.
    92110        Hooks::addAction('wp_enqueue_scripts', Assets::class, 'loadFrontendAssets');
     111        Hooks::addAction('givewp_donation_confirmation_receipt_showing', Assets::class, 'loadReceiptScripts');
    93112    }
    94113}
  • give-double-the-donation/tags/2.1.0/src/DoubleTheDonation/Assets.php

    r3072620 r3332990  
    11<?php
     2
    23namespace GiveDoubleTheDonation\DoubleTheDonation;
    34
     
    89 * @copyright   Copyright (c) 2020, GiveWP
    910 */
    10 class Assets {
     11class Assets
     12{
    1113
    12     /**
    13      * Load add-on backend assets.
    14      *
    15      * @since 1.0.0
    16      * @return void
    17      */
    18     public static function loadBackendAssets() {
     14    /**
     15     * Load add-on backend assets.
     16     *
     17     * @since 1.0.0
     18     * @return void
     19     */
     20    public static function loadBackendAssets()
     21    {
    1922        $assets = require(GIVE_DTD_DIR . 'build/backend.asset.php');
    2023
    21         wp_enqueue_script(
    22             'give-double-the-donation-script-backend',
     24        wp_enqueue_script(
     25            'give-double-the-donation-script-backend',
    2326            GIVE_DTD_URL . 'build/backend.js',
    2427            $assets['dependencies'],
    2528            $assets['version'],
    26             true
    27         );
    28     }
     29            true
     30        );
     31    }
    2932
    30     /**
    31      * Load add-on front-end assets.
    32      *
    33      * @since 1.0.0
    34      * @return void
    35      */
    36     public static function loadFrontendAssets() {
     33    /**
     34     * Load add-on front-end assets.
     35     *
     36     * @since 1.0.0
     37     * @return void
     38     */
     39    public static function loadFrontendAssets()
     40    {
    3741        $assets = require(GIVE_DTD_DIR . 'build/frontend.asset.php');
    3842
     
    4044
    4145        wp_enqueue_script(
    42             'give-double-the-donation-script',
    43             'https://doublethedonation.com/api/js/ddplugin.js',
    44             []
    45         );
     46            'give-double-the-donation-script',
     47            'https://doublethedonation.com/api/js/ddplugin.js',
     48            []
     49        );
    4650
    47         wp_enqueue_style(
    48             'give-double-the-donation-style',
    49             'https://doublethedonation.com/api/css/ddplugin.css',
    50             []
    51         );
     51        wp_enqueue_style(
     52            'give-double-the-donation-style',
     53            'https://doublethedonation.com/api/css/ddplugin.css',
     54            []
     55        );
    5256
    5357        wp_enqueue_script(
     
    5660            $assets['dependencies'],
    5761            $assets['version'],
    58             true
    59         );
    60     }
     62            true
     63        );
     64    }
     65
     66    /**
     67     * @since 2.1.0
     68     */
     69    public function loadReceiptScripts()
     70    {
     71        if ($dtdPublicKey = give_get_option('public_dtd_key')) {
     72            $this->loadFrontendAssets();
     73
     74            wp_register_script('givewp-dtd-receipt-script', null);
     75            wp_add_inline_script(
     76                'givewp-dtd-receipt-script',
     77                sprintf("var DDCONF = {'API_KEY': '%s', 'GIVE_ENDPOINT': '%s'}", $dtdPublicKey, rest_url('givewp/dtd/donation/')),
     78                'before'
     79            );
     80            wp_enqueue_script('givewp-dtd-receipt-script', null, ['give-double-the-donation-script']);
     81        }
     82    }
    6183}
  • give-double-the-donation/tags/2.1.0/src/DoubleTheDonation/FormExtension/Actions/ConvertBlockToField.php

    r3207135 r3332990  
    33namespace GiveDoubleTheDonation\DoubleTheDonation\FormExtension\Actions;
    44
    5 use Give\Donations\Models\Donation;
    65use Give\Framework\Blocks\BlockModel;
    76use Give\Framework\FieldsAPI\Contracts\Node;
    87use Give\Framework\FieldsAPI\Exceptions\EmptyNameException;
    9 use GiveDoubleTheDonation\Addon\View;
    108use GiveDoubleTheDonation\DoubleTheDonation\FormExtension\Actions\FieldScope\HandleData;
    119use GiveDoubleTheDonation\DoubleTheDonation\FormExtension\Field as DoubleTheDonationField;
     
    3028            ->showInReceipt()
    3129            ->receiptLabel(__('Company Matching', 'give-double-the-donation'))
    32             ->receiptValue(function(DoubleTheDonationField $field, Donation $donation) {
    33                 return View::load('dtd-receipt', [
    34                     'donation' => $donation,
    35                 ]);
    36             })
    3730            ->tap(function (DoubleTheDonationField $field) use ($block) {
    3831                $field
  • give-double-the-donation/tags/2.1.0/src/DoubleTheDonation/FormExtension/Actions/FieldScope/HandleData.php

    r3207135 r3332990  
    5454     * Save payment meta
    5555     *
     56     * @since 2.1.0 update visibility
    5657     * @since 2.0.0
    5758     */
    58     private function save(array $companyData, Donation $donation)
     59    public function save(array $companyData, Donation $donation)
    5960    {
    6061        foreach ($companyData as $name => $value) {
     
    8283     * Send data to DTD 360match pro
    8384     *
     85     * @since 2.1.0 update visibility
    8486     * @since 2.0.2
    8587     */
    86     private function send(array $companyData, Donation $donation): void
     88    public function send(array $companyData, Donation $donation): void
    8789    {
    8890        if ( ! $dtdPublicKey = give_get_option('public_dtd_key')) {
     
    132134        ]);
    133135    }
     136
     137    /**
     138     * Remove payment meta added on donation confirmation page
     139     *
     140     * @since 2.1.0
     141     */
     142    public function remove(Donation $donation)
     143    {
     144        $fields = [
     145            'company_id',
     146            'company_name',
     147            'entered_text'
     148        ];
     149
     150        foreach ($fields as $name => $value) {
     151            give_delete_meta(
     152                $donation->id,
     153                'doublethedonation_' . $name,
     154            );
     155        }
     156
     157        give_delete_meta(
     158            $donation->id,
     159            '_give_donation_company',
     160        );
     161
     162        give()->donor_meta->delete_meta(
     163            $donation->donorId,
     164            '_give_donor_company',
     165        );
     166    }
    134167}
  • give-double-the-donation/tags/2.1.0/src/DoubleTheDonation/FormExtension/ServiceProvider.php

    r3072620 r3332990  
    66use Give\ServiceProviders\ServiceProvider as ServiceProviderInterface;
    77use GiveDoubleTheDonation\DoubleTheDonation\FormExtension\Actions\ConvertBlockToField;
    8 use GiveDoubleTheDonation\DoubleTheDonation\FormExtension\Actions\DisplayFieldLabel;
     8use GiveDoubleTheDonation\DoubleTheDonation\FormExtension\Actions\DisplayField;
    99use GiveDoubleTheDonation\DoubleTheDonation\FormExtension\Actions\LoadAssets;
    1010use GiveDoubleTheDonation\DoubleTheDonation\FormExtension\Email\EmailTags;
     
    3131
    3232        Hooks::addFilter('givewp_donation_form_block_render_givewp/dtd', ConvertBlockToField::class, '__invoke', 10, 4);
    33         Hooks::addFilter('givewp_donation_confirmation_page_field_label_for_dtd', DisplayFieldLabel::class, '__invoke', 10, 3);
     33        Hooks::addFilter('givewp_donation_confirmation_page_field_value_for_dtd', DisplayField::class, 'value', 10, 3);
    3434
    3535        Hooks::addFilter('give_email_tags', EmailTags::class, 'register');
  • give-double-the-donation/tags/2.1.0/src/DoubleTheDonation/Payment.php

    r3207135 r3332990  
    22
    33namespace GiveDoubleTheDonation\DoubleTheDonation;
     4
     5use Give\Donations\Models\Donation;
    46
    57class Payment {
     
    5254     */
    5355    public function addDonationToDTD( $payment_id, $payment_data ) {
    54 
    5556        // API Key check
    5657        $dtdPublicKey = give_get_option( 'public_dtd_key', false );
  • give-double-the-donation/tags/2.1.0/src/DoubleTheDonation/resources/js/frontend/give-double-the-donation.js

    r2413638 r3332990  
    44            if ( ! input.hasAttribute( 'data-doublethedonation-widget-id' ) ) {
    55                window.doublethedonation.plugin.load_streamlined_input( input );
     6
     7                input.addEventListener('change', () => {
     8                    const donationId = input.dataset.donationId;
     9                    const receiptId = input.dataset.receiptId;
     10                    // do we have an event from DTD we can use??
     11                    window.setTimeout(async () => {
     12                        const companyId = document.querySelector('[name="doublethedonation_company_id"]').value;
     13                        const companyName = document.querySelector('[name="doublethedonation_company_name"]').value;
     14                        const enteredText = document.querySelector('[name="doublethedonation_entered_text"]').value;
     15
     16                        const response = await fetch(DDCONF.GIVE_ENDPOINT + donationId, {
     17                            method: 'POST',
     18                            headers: {
     19                                'Content-Type': 'application/json',
     20                            },
     21                            body: JSON.stringify({
     22                                companyId,
     23                                companyName,
     24                                enteredText,
     25                                receiptId
     26                            }),
     27                        });
     28
     29                        // select different company
     30                        document.querySelectorAll('.wrongcompany a')?.forEach((link) => {
     31                            link.addEventListener('click', () => {
     32                                const response = fetch(DDCONF.GIVE_ENDPOINT + donationId + `?receiptId=${receiptId}`, {
     33                                    method: 'DELETE',
     34                                });
     35                            });
     36                        });
     37                    }, 500)
     38                });
    639            }
    740        } );
     
    942
    1043    document.addEventListener( 'give_gateway_loaded', initializePlugin );
    11 
    12     initializePlugin();
     44    document.addEventListener('DOMContentLoaded', initializePlugin);
    1345}
  • give-double-the-donation/tags/2.1.0/src/DoubleTheDonation/resources/views/dtd-receipt.php

    r3207135 r3332990  
    66/**
    77 * @var Donation $donation
     8 * @var string $receiptId
    89 */
    910
     
    1112
    1213if ( ! $companyId) {
     14    printf('<div class="dd-company-name-input" data-donation-id="%s" data-receipt-id="%s"></div>', $donation->id, $receiptId);
    1315    return;
    1416}
  • give-double-the-donation/tags/2.1.0/vendor/autoload.php

    r3072620 r3332990  
    1515        }
    1616    }
    17     trigger_error(
    18         $err,
    19         E_USER_ERROR
    20     );
     17    throw new RuntimeException($err);
    2118}
    2219
  • give-double-the-donation/tags/2.1.0/vendor/composer/InstalledVersions.php

    r3207135 r3332990  
    2828{
    2929    /**
     30     * @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
     31     * @internal
     32     */
     33    private static $selfDir = null;
     34
     35    /**
    3036     * @var mixed[]|null
    3137     * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
    3238     */
    3339    private static $installed;
     40
     41    /**
     42     * @var bool
     43     */
     44    private static $installedIsLocalDir;
    3445
    3546    /**
     
    310321        self::$installed = $data;
    311322        self::$installedByVendor = array();
     323
     324        // when using reload, we disable the duplicate protection to ensure that self::$installed data is
     325        // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
     326        // so we have to assume it does not, and that may result in duplicate data being returned when listing
     327        // all installed packages for example
     328        self::$installedIsLocalDir = false;
     329    }
     330
     331    /**
     332     * @return string
     333     */
     334    private static function getSelfDir()
     335    {
     336        if (self::$selfDir === null) {
     337            self::$selfDir = strtr(__DIR__, '\\', '/');
     338        }
     339
     340        return self::$selfDir;
    312341    }
    313342
     
    326355
    327356        if (self::$canGetVendors) {
     357            $selfDir = self::getSelfDir();
    328358            foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
     359                $vendorDir = strtr($vendorDir, '\\', '/');
    329360                if (isset(self::$installedByVendor[$vendorDir])) {
    330361                    $installed[] = self::$installedByVendor[$vendorDir];
     
    334365                    self::$installedByVendor[$vendorDir] = $required;
    335366                    $installed[] = $required;
    336                     if (strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
     367                    if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
    337368                        self::$installed = $required;
    338                         $copiedLocalDir = true;
     369                        self::$installedIsLocalDir = true;
    339370                    }
     371                }
     372                if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
     373                    $copiedLocalDir = true;
    340374                }
    341375            }
  • give-double-the-donation/trunk/build/frontend.asset.php

    r3072620 r3332990  
    1 <?php return array('dependencies' => array(), 'version' => '95b1e6ad157050134353');
     1<?php return array('dependencies' => array(), 'version' => 'cb2ce59061ec431a0631');
  • give-double-the-donation/trunk/build/frontend.js

    r3072620 r3332990  
    1 (()=>{if(window.doublethedonation){function e(){document.querySelectorAll(".dd-company-name-input").forEach((e=>{e.hasAttribute("data-doublethedonation-widget-id")||window.doublethedonation.plugin.load_streamlined_input(e)}))}document.addEventListener("give_gateway_loaded",e),e()}})();
     1(()=>{if(window.doublethedonation){function e(){document.querySelectorAll(".dd-company-name-input").forEach((e=>{e.hasAttribute("data-doublethedonation-widget-id")||(window.doublethedonation.plugin.load_streamlined_input(e),e.addEventListener("change",(()=>{const t=e.dataset.donationId,n=e.dataset.receiptId;window.setTimeout((async()=>{const e=document.querySelector('[name="doublethedonation_company_id"]').value,o=document.querySelector('[name="doublethedonation_company_name"]').value,d=document.querySelector('[name="doublethedonation_entered_text"]').value;await fetch(DDCONF.GIVE_ENDPOINT+t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({companyId:e,companyName:o,enteredText:d,receiptId:n})}),document.querySelectorAll(".wrongcompany a")?.forEach((e=>{e.addEventListener("click",(()=>{fetch(DDCONF.GIVE_ENDPOINT+t+`?receiptId=${n}`,{method:"DELETE"})}))}))}),500)})))}))}document.addEventListener("give_gateway_loaded",e),document.addEventListener("DOMContentLoaded",e)}})();
  • give-double-the-donation/trunk/changelog.txt

    r3207135 r3332990  
    11*** Give - Double the Donation changelog ***
     2
     32025-07-23 - version 2.1.0
     4- New: Added compatibility with recurring donations
     5- New: Added additional company match field to the donation confirmation page
    26
    372024-12-12 - version 2.0.2
  • give-double-the-donation/trunk/give-double-the-donation.php

    r3207135 r3332990  
    44 * Plugin URI:  https://givewp.com/addons/give-double-the-donation/
    55 * Description: Easily integrate with the Double the Donation employer matching platform.
    6  * Version:     2.0.2
     6 * Version:     2.1.0
    77 * Author:      GiveWP
    8  * Requires at least: 6.3
     8 * Requires at least: 6.6
    99 * Requires PHP: 7.2
    1010 * Author URI:  https://givewp.com/
     
    2626
    2727// Versions
    28 define( 'GIVE_DTD_VERSION', '2.0.2' );
     28define( 'GIVE_DTD_VERSION', '2.1.0' );
    2929define( 'GIVE_DTD_MIN_GIVE_VERSION', '3.8.0' );
    3030
  • give-double-the-donation/trunk/readme.txt

    r3207135 r3332990  
    33Donate link: https://givewp.com/
    44Tags: givewp, double the donation, employer matching, company matching donation, employer matching donations
    5 Requires at least: 6.3
    6 Tested up to: 6.7
     5Requires at least: 6.6
     6Tested up to: 6.8
    77Requires PHP: 7.2
    8 Stable tag: 2.0.2
     8Stable tag: 2.1.0
    99Requires Give: 3.8.0
    1010License: GPLv3
     
    1717Empower your GiveWP donors to have their company match their donations with the most powerful Company Matching platform: Double the Donation.
    1818
    19 With this GiveWP add-on, simply add your Double the Donation API keys into the settings, then each of your forms can be enabled to accept company matching. 
     19With this GiveWP add-on, simply add your Double the Donation API keys into the settings, then each of your forms can be enabled to accept company matching.
    2020
    2121**ABOUT DOUBLE THE DONATION:**
    22 Automate your matching gift fundraising with the industry-leading solution from Double the Donation. Double the Donation provides nonprofits with tools to identify match-eligible donors, drive matches to completion, and gain actionable insights. Our unique integration with GiveWP integrates directly into your donation forms, to capture employment information and follow up appropriately with donors about matching gifts. 
     22Automate your matching gift fundraising with the industry-leading solution from Double the Donation. Double the Donation provides nonprofits with tools to identify match-eligible donors, drive matches to completion, and gain actionable insights. Our unique integration with GiveWP integrates directly into your donation forms, to capture employment information and follow up appropriately with donors about matching gifts.
    2323
    2424**ABOUT OUR FREE ADD-ONS**
     
    3131= Minimum Requirements =
    3232
    33 * An active subscription to Double the Donation. 
    34 * WordPress 6.3 or greater
     33* An active subscription to Double the Donation.
     34* WordPress 6.6 or greater
    3535* PHP version 7.2 or greater
    3636* MySQL version 5.7 or greater
     
    5858The companies listed in the Double the Donation dropdown all registered with Double the Donation to provide their employees this opportunity. If your company does not appear there, then most likely they have not yet applied with Double the Donation. You can submit on their behalf, or [send them here to apply](https://doublethedonation.com/matching-gift-database/new-companies-with-matching-gift-programs/).
    5959
    60 = I set my company to match, what happens next? = 
     60= I set my company to match, what happens next? =
    6161Your company will get an email and you will as well with next steps to follow. If you have any trouble with this process, contact [Double the Donation directly here](https://support.doublethedonation.com/portal/en/home).
    6262
    63 == Screenshots == 
     63== Screenshots ==
    6464
    65 1. The company search is powered by Double the Donation. It's fast and intuitive for your donors. 
     651. The company search is powered by Double the Donation. It's fast and intuitive for your donors.
    6666
    67672. Integrating Double the Donation with GiveWP is as simple as inserting your API keys in the settings fields.
     
    7070
    7171== Changelog ==
     72
     73= 2.1.0: July 23rd, 2025 =
     74* New: Added compatibility with recurring donations
     75* New: Added additional company match field to the donation confirmation page
    7276
    7377= 2.0.2: December 12th, 2024 =
  • give-double-the-donation/trunk/src/DoubleTheDonation/AddonServiceProvider.php

    r3207135 r3332990  
    33namespace GiveDoubleTheDonation\DoubleTheDonation;
    44
     5use Give\Donations\Models\Donation;
    56use Give\Helpers\Hooks;
    67use Give\ServiceProviders\ServiceProvider;
     
    1011use GiveDoubleTheDonation\Addon\License;
    1112use GiveDoubleTheDonation\DoubleTheDonation\Actions\CheckCredentials;
     13use GiveDoubleTheDonation\DoubleTheDonation\API\REST\CompanyMatching;
    1214use GiveDoubleTheDonation\DoubleTheDonation\Helpers\SettingsPage as SettingsPageRegister;
    1315
     
    3840        Hooks::addAction('give_donation_form_after_email', DonationForm::class, 'employerMatchField');
    3941
    40         // handle v2 forms stuff
    41         if (isset($_POST) && ! isset($_POST['dtd'])) {
    42             Hooks::addAction('give_insert_payment', Payment::class, 'addPaymentMeta', 10, 2);
    43             Hooks::addAction('give_insert_payment', Payment::class, 'addDonationToDTD', 11, 2);
    44         }
     42        add_action('give_insert_payment', function($payment_id, $payment_data) {
     43            // handle for v2 forms (v3 forms uses field scope)
     44            if (isset($_POST) && !isset($_POST['dtd'])) {
     45                give(Payment::class)->addPaymentMeta($payment_id, $payment_data);
     46
     47                $donation = Donation::find((int)$payment_id);
     48
     49                // handle for single donations only
     50                if ($donation->type->isSingle()) {
     51                    give(Payment::class)->addDonationToDTD($payment_id, $payment_data);
     52                }
     53            }
     54        });
     55
     56        /**
     57         * @since 2.1.0 add support for recurring donations
     58         */
     59        Hooks::addAction('give_recurring_record_payment', Payment::class, 'addDonationToDTD', 10, 2);
    4560
    4661        // Show Receipt info
     
    89104    private function loadFrontend()
    90105    {
     106        // @since 2.1.0
     107        Hooks::addAction('rest_api_init', CompanyMatching::class);
     108
    91109        // Load front-end assets.
    92110        Hooks::addAction('wp_enqueue_scripts', Assets::class, 'loadFrontendAssets');
     111        Hooks::addAction('givewp_donation_confirmation_receipt_showing', Assets::class, 'loadReceiptScripts');
    93112    }
    94113}
  • give-double-the-donation/trunk/src/DoubleTheDonation/Assets.php

    r3072620 r3332990  
    11<?php
     2
    23namespace GiveDoubleTheDonation\DoubleTheDonation;
    34
     
    89 * @copyright   Copyright (c) 2020, GiveWP
    910 */
    10 class Assets {
     11class Assets
     12{
    1113
    12     /**
    13      * Load add-on backend assets.
    14      *
    15      * @since 1.0.0
    16      * @return void
    17      */
    18     public static function loadBackendAssets() {
     14    /**
     15     * Load add-on backend assets.
     16     *
     17     * @since 1.0.0
     18     * @return void
     19     */
     20    public static function loadBackendAssets()
     21    {
    1922        $assets = require(GIVE_DTD_DIR . 'build/backend.asset.php');
    2023
    21         wp_enqueue_script(
    22             'give-double-the-donation-script-backend',
     24        wp_enqueue_script(
     25            'give-double-the-donation-script-backend',
    2326            GIVE_DTD_URL . 'build/backend.js',
    2427            $assets['dependencies'],
    2528            $assets['version'],
    26             true
    27         );
    28     }
     29            true
     30        );
     31    }
    2932
    30     /**
    31      * Load add-on front-end assets.
    32      *
    33      * @since 1.0.0
    34      * @return void
    35      */
    36     public static function loadFrontendAssets() {
     33    /**
     34     * Load add-on front-end assets.
     35     *
     36     * @since 1.0.0
     37     * @return void
     38     */
     39    public static function loadFrontendAssets()
     40    {
    3741        $assets = require(GIVE_DTD_DIR . 'build/frontend.asset.php');
    3842
     
    4044
    4145        wp_enqueue_script(
    42             'give-double-the-donation-script',
    43             'https://doublethedonation.com/api/js/ddplugin.js',
    44             []
    45         );
     46            'give-double-the-donation-script',
     47            'https://doublethedonation.com/api/js/ddplugin.js',
     48            []
     49        );
    4650
    47         wp_enqueue_style(
    48             'give-double-the-donation-style',
    49             'https://doublethedonation.com/api/css/ddplugin.css',
    50             []
    51         );
     51        wp_enqueue_style(
     52            'give-double-the-donation-style',
     53            'https://doublethedonation.com/api/css/ddplugin.css',
     54            []
     55        );
    5256
    5357        wp_enqueue_script(
     
    5660            $assets['dependencies'],
    5761            $assets['version'],
    58             true
    59         );
    60     }
     62            true
     63        );
     64    }
     65
     66    /**
     67     * @since 2.1.0
     68     */
     69    public function loadReceiptScripts()
     70    {
     71        if ($dtdPublicKey = give_get_option('public_dtd_key')) {
     72            $this->loadFrontendAssets();
     73
     74            wp_register_script('givewp-dtd-receipt-script', null);
     75            wp_add_inline_script(
     76                'givewp-dtd-receipt-script',
     77                sprintf("var DDCONF = {'API_KEY': '%s', 'GIVE_ENDPOINT': '%s'}", $dtdPublicKey, rest_url('givewp/dtd/donation/')),
     78                'before'
     79            );
     80            wp_enqueue_script('givewp-dtd-receipt-script', null, ['give-double-the-donation-script']);
     81        }
     82    }
    6183}
  • give-double-the-donation/trunk/src/DoubleTheDonation/FormExtension/Actions/ConvertBlockToField.php

    r3207135 r3332990  
    33namespace GiveDoubleTheDonation\DoubleTheDonation\FormExtension\Actions;
    44
    5 use Give\Donations\Models\Donation;
    65use Give\Framework\Blocks\BlockModel;
    76use Give\Framework\FieldsAPI\Contracts\Node;
    87use Give\Framework\FieldsAPI\Exceptions\EmptyNameException;
    9 use GiveDoubleTheDonation\Addon\View;
    108use GiveDoubleTheDonation\DoubleTheDonation\FormExtension\Actions\FieldScope\HandleData;
    119use GiveDoubleTheDonation\DoubleTheDonation\FormExtension\Field as DoubleTheDonationField;
     
    3028            ->showInReceipt()
    3129            ->receiptLabel(__('Company Matching', 'give-double-the-donation'))
    32             ->receiptValue(function(DoubleTheDonationField $field, Donation $donation) {
    33                 return View::load('dtd-receipt', [
    34                     'donation' => $donation,
    35                 ]);
    36             })
    3730            ->tap(function (DoubleTheDonationField $field) use ($block) {
    3831                $field
  • give-double-the-donation/trunk/src/DoubleTheDonation/FormExtension/Actions/FieldScope/HandleData.php

    r3207135 r3332990  
    5454     * Save payment meta
    5555     *
     56     * @since 2.1.0 update visibility
    5657     * @since 2.0.0
    5758     */
    58     private function save(array $companyData, Donation $donation)
     59    public function save(array $companyData, Donation $donation)
    5960    {
    6061        foreach ($companyData as $name => $value) {
     
    8283     * Send data to DTD 360match pro
    8384     *
     85     * @since 2.1.0 update visibility
    8486     * @since 2.0.2
    8587     */
    86     private function send(array $companyData, Donation $donation): void
     88    public function send(array $companyData, Donation $donation): void
    8789    {
    8890        if ( ! $dtdPublicKey = give_get_option('public_dtd_key')) {
     
    132134        ]);
    133135    }
     136
     137    /**
     138     * Remove payment meta added on donation confirmation page
     139     *
     140     * @since 2.1.0
     141     */
     142    public function remove(Donation $donation)
     143    {
     144        $fields = [
     145            'company_id',
     146            'company_name',
     147            'entered_text'
     148        ];
     149
     150        foreach ($fields as $name => $value) {
     151            give_delete_meta(
     152                $donation->id,
     153                'doublethedonation_' . $name,
     154            );
     155        }
     156
     157        give_delete_meta(
     158            $donation->id,
     159            '_give_donation_company',
     160        );
     161
     162        give()->donor_meta->delete_meta(
     163            $donation->donorId,
     164            '_give_donor_company',
     165        );
     166    }
    134167}
  • give-double-the-donation/trunk/src/DoubleTheDonation/FormExtension/ServiceProvider.php

    r3072620 r3332990  
    66use Give\ServiceProviders\ServiceProvider as ServiceProviderInterface;
    77use GiveDoubleTheDonation\DoubleTheDonation\FormExtension\Actions\ConvertBlockToField;
    8 use GiveDoubleTheDonation\DoubleTheDonation\FormExtension\Actions\DisplayFieldLabel;
     8use GiveDoubleTheDonation\DoubleTheDonation\FormExtension\Actions\DisplayField;
    99use GiveDoubleTheDonation\DoubleTheDonation\FormExtension\Actions\LoadAssets;
    1010use GiveDoubleTheDonation\DoubleTheDonation\FormExtension\Email\EmailTags;
     
    3131
    3232        Hooks::addFilter('givewp_donation_form_block_render_givewp/dtd', ConvertBlockToField::class, '__invoke', 10, 4);
    33         Hooks::addFilter('givewp_donation_confirmation_page_field_label_for_dtd', DisplayFieldLabel::class, '__invoke', 10, 3);
     33        Hooks::addFilter('givewp_donation_confirmation_page_field_value_for_dtd', DisplayField::class, 'value', 10, 3);
    3434
    3535        Hooks::addFilter('give_email_tags', EmailTags::class, 'register');
  • give-double-the-donation/trunk/src/DoubleTheDonation/Payment.php

    r3207135 r3332990  
    22
    33namespace GiveDoubleTheDonation\DoubleTheDonation;
     4
     5use Give\Donations\Models\Donation;
    46
    57class Payment {
     
    5254     */
    5355    public function addDonationToDTD( $payment_id, $payment_data ) {
    54 
    5556        // API Key check
    5657        $dtdPublicKey = give_get_option( 'public_dtd_key', false );
  • give-double-the-donation/trunk/src/DoubleTheDonation/resources/js/frontend/give-double-the-donation.js

    r2413638 r3332990  
    44            if ( ! input.hasAttribute( 'data-doublethedonation-widget-id' ) ) {
    55                window.doublethedonation.plugin.load_streamlined_input( input );
     6
     7                input.addEventListener('change', () => {
     8                    const donationId = input.dataset.donationId;
     9                    const receiptId = input.dataset.receiptId;
     10                    // do we have an event from DTD we can use??
     11                    window.setTimeout(async () => {
     12                        const companyId = document.querySelector('[name="doublethedonation_company_id"]').value;
     13                        const companyName = document.querySelector('[name="doublethedonation_company_name"]').value;
     14                        const enteredText = document.querySelector('[name="doublethedonation_entered_text"]').value;
     15
     16                        const response = await fetch(DDCONF.GIVE_ENDPOINT + donationId, {
     17                            method: 'POST',
     18                            headers: {
     19                                'Content-Type': 'application/json',
     20                            },
     21                            body: JSON.stringify({
     22                                companyId,
     23                                companyName,
     24                                enteredText,
     25                                receiptId
     26                            }),
     27                        });
     28
     29                        // select different company
     30                        document.querySelectorAll('.wrongcompany a')?.forEach((link) => {
     31                            link.addEventListener('click', () => {
     32                                const response = fetch(DDCONF.GIVE_ENDPOINT + donationId + `?receiptId=${receiptId}`, {
     33                                    method: 'DELETE',
     34                                });
     35                            });
     36                        });
     37                    }, 500)
     38                });
    639            }
    740        } );
     
    942
    1043    document.addEventListener( 'give_gateway_loaded', initializePlugin );
    11 
    12     initializePlugin();
     44    document.addEventListener('DOMContentLoaded', initializePlugin);
    1345}
  • give-double-the-donation/trunk/src/DoubleTheDonation/resources/views/dtd-receipt.php

    r3207135 r3332990  
    66/**
    77 * @var Donation $donation
     8 * @var string $receiptId
    89 */
    910
     
    1112
    1213if ( ! $companyId) {
     14    printf('<div class="dd-company-name-input" data-donation-id="%s" data-receipt-id="%s"></div>', $donation->id, $receiptId);
    1315    return;
    1416}
  • give-double-the-donation/trunk/vendor/autoload.php

    r3072620 r3332990  
    1515        }
    1616    }
    17     trigger_error(
    18         $err,
    19         E_USER_ERROR
    20     );
     17    throw new RuntimeException($err);
    2118}
    2219
  • give-double-the-donation/trunk/vendor/composer/InstalledVersions.php

    r3207135 r3332990  
    2828{
    2929    /**
     30     * @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
     31     * @internal
     32     */
     33    private static $selfDir = null;
     34
     35    /**
    3036     * @var mixed[]|null
    3137     * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
    3238     */
    3339    private static $installed;
     40
     41    /**
     42     * @var bool
     43     */
     44    private static $installedIsLocalDir;
    3445
    3546    /**
     
    310321        self::$installed = $data;
    311322        self::$installedByVendor = array();
     323
     324        // when using reload, we disable the duplicate protection to ensure that self::$installed data is
     325        // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
     326        // so we have to assume it does not, and that may result in duplicate data being returned when listing
     327        // all installed packages for example
     328        self::$installedIsLocalDir = false;
     329    }
     330
     331    /**
     332     * @return string
     333     */
     334    private static function getSelfDir()
     335    {
     336        if (self::$selfDir === null) {
     337            self::$selfDir = strtr(__DIR__, '\\', '/');
     338        }
     339
     340        return self::$selfDir;
    312341    }
    313342
     
    326355
    327356        if (self::$canGetVendors) {
     357            $selfDir = self::getSelfDir();
    328358            foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
     359                $vendorDir = strtr($vendorDir, '\\', '/');
    329360                if (isset(self::$installedByVendor[$vendorDir])) {
    330361                    $installed[] = self::$installedByVendor[$vendorDir];
     
    334365                    self::$installedByVendor[$vendorDir] = $required;
    335366                    $installed[] = $required;
    336                     if (strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
     367                    if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
    337368                        self::$installed = $required;
    338                         $copiedLocalDir = true;
     369                        self::$installedIsLocalDir = true;
    339370                    }
     371                }
     372                if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
     373                    $copiedLocalDir = true;
    340374                }
    341375            }
Note: See TracChangeset for help on using the changeset viewer.