Skip to content

Commit

Permalink
Merge branch 'epic/campaigns' into feature/campaign-banner-GIVE-2312
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshuaHungDinh authored Mar 11, 2025
2 parents fb22f6e + dab1df0 commit a1db6f8
Show file tree
Hide file tree
Showing 23 changed files with 104 additions and 45 deletions.
4 changes: 2 additions & 2 deletions give.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Description: The most robust, flexible, and intuitive way to accept donations on WordPress.
* Author: GiveWP
* Author URI: https://givewp.com/
* Version: 3.22.0
* Version: 3.22.1
* Requires at least: 6.5
* Requires PHP: 7.2
* Text Domain: give
Expand Down Expand Up @@ -420,7 +420,7 @@ private function setup_constants()
{
// Plugin version.
if (!defined('GIVE_VERSION')) {
define('GIVE_VERSION', '3.22.0');
define('GIVE_VERSION', '3.22.1');
}

// Plugin Root File.
Expand Down
5 changes: 5 additions & 0 deletions includes/admin/reports/reports.php
Original file line number Diff line number Diff line change
Expand Up @@ -298,10 +298,15 @@ function give_reports_gateways_table() {
/**
* Renders the Reports Earnings Graphs
*
* @since 3.22.1 added permissions check
* @since 1.0
* @return void
*/
function give_reports_earnings() {
if (!current_user_can('view_give_reports')){
wp_die(__('You do not have permission to access this report', 'give'), __('Error', 'give'), ['response' => 403]);
}

?>
<div class="tablenav top reports-table-nav">
<h2 class="reports-earnings-title screen-reader-text"><?php _e( 'Revenue Report', 'give' ); ?></h2>
Expand Down
5 changes: 4 additions & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Tags: donation, donate, recurring donations, fundraising, crowdfunding
Requires at least: 6.5
Tested up to: 6.7
Requires PHP: 7.2
Stable tag: 3.22.0
Stable tag: 3.22.1
License: GPLv3
License URI: http://www.gnu.org/licenses/gpl-3.0.html

Expand Down Expand Up @@ -266,6 +266,9 @@ You can report security bugs through the Patchstack Vulnerability Disclosure Pro
10. Use almost any payment gateway integration with GiveWP through our add-ons or by creating your own add-on.

== Changelog ==
= 3.22.1: March 7th, 2025 =
* Security: Added a permission check to a GiveWP reporting request (CVE-2025-2025)

= 3.22.0: February 26th, 2025 =
* New: Added initial WPML and Polylang multilingual translation support to visual form builder forms that currently excludes custom fields
* Fix: Resolved a validation issue with PayPal donations when using Akismet
Expand Down
31 changes: 19 additions & 12 deletions src/Campaigns/Actions/CampaignPageTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace Give\Campaigns\Actions;

use Give\Campaigns\Models\Campaign;
use Give\Campaigns\ValueObjects\CampaignStatus;
use Give\Framework\Views\View;

/**
Expand All @@ -16,7 +15,7 @@ class CampaignPageTemplate
*/
public function registerTemplate()
{
if ( ! $this->canRegisterBlockTemplate()) {
if (!$this->canRegisterBlockTemplate()) {
return;
}

Expand All @@ -39,7 +38,7 @@ public function loadTemplate($template)
'give_campaign_page' === get_query_var('post_type')
&& current_theme_supports('block-templates')
) {
if ( ! $this->isPageVisible()) {
if (!$this->isPageVisible()) {
status_header(404);

return get_404_template();
Expand All @@ -64,25 +63,33 @@ private function canRegisterBlockTemplate(): bool
}

/**
*
* @unreleased
*/
private function isPageVisible(): bool
{
$campaign = Campaign::find(get_post_field('campaignId'));
$campaignId = get_post_field('campaignId');

if ( ! $campaign) {
if (!$campaignId) {
return false;
}

// Allow logged in admin users to preview the page
if (
! current_user_can('manage_options')
&& ! $campaign->enableCampaignPage
&& $campaign->status->getValue() !== CampaignStatus::ACTIVE()
) {
$campaign = Campaign::find($campaignId);

if (!$campaign) {
return false;
}

// if the campaign page is disabled, no one can see it
if (!$campaign->enableCampaignPage) {
return false;
}

return true;
// logged-in users can see the page if the campaign is active or draft
if (current_user_can('manage_options') && ($campaign->status->isActive() || $campaign->status->isDraft()) ) {
return true;
}

return $campaign->status->isActive();
}
}
4 changes: 3 additions & 1 deletion src/Campaigns/Blocks/CampaignComments/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,11 @@
}
}
},
"example": {},
"textdomain": "give",
"render": "file:./render.php",
"viewScript": "file:../../../../build/campaignCommentsBlockApp.js",
"editorScript": "file:../../../../build/campaignBlocks.js",
"style": "file:../../../../build/campaignCommentsBlockApp.css"
"style": "file:../../../../build/campaignCommentsBlockApp.css",
"editorStyle": "file:../../../../assets/dist/css/design-system/foundation.css"
}
1 change: 1 addition & 0 deletions src/Campaigns/Blocks/CampaignCover/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"anchor": true,
"className": true
},
"example":{},
"textdomain": "give",
"render": "file:./render.php",
"style": "file:../../../../build/campaignCoverBlock.css"
Expand Down
1 change: 1 addition & 0 deletions src/Campaigns/Blocks/CampaignDonations/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"supports": {
"className": true
},
"example": {},
"textdomain": "give",
"render": "file:./render.php",
"style": "file:../../../../build/campaignDonationsBlockApp.css"
Expand Down
1 change: 1 addition & 0 deletions src/Campaigns/Blocks/CampaignDonors/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"supports": {
"className": true
},
"example": {},
"textdomain": "give",
"render": "file:./render.php",
"style": "file:../../../../build/campaignDonorsBlockApp.css"
Expand Down
1 change: 1 addition & 0 deletions src/Campaigns/Blocks/CampaignGoal/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"type": "number"
}
},
"example": {},
"textdomain": "give",
"viewScript": "file:../../../../build/campaignGoalBlockApp.js",
"style": "file:../../../../build/campaignGoalBlockApp.css",
Expand Down
1 change: 1 addition & 0 deletions src/Campaigns/Blocks/CampaignGrid/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"default": true
}
},
"example": {},
"textdomain": "give",
"viewScript": "file:../../../../build/campaignGridApp.js",
"viewStyle": "file:../../../../build/campaignGridApp.css",
Expand Down
1 change: 1 addition & 0 deletions src/Campaigns/Blocks/CampaignStats/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
}
}
},
"example": {},
"textdomain": "give",
"render": "file:./render.php",
"viewScript": "file:../../../../build/campaignStatsBlockApp.js",
Expand Down
5 changes: 5 additions & 0 deletions src/Campaigns/Blocks/CampaignTitle/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@
}
}
},
"example": {
"attributes": {
"textAlign": "center"
}
},
"textdomain": "give",
"editorStyle": "file:../../../../build/campaignTitleBlock.css",
"render": "file:./render.php"
Expand Down
1 change: 1 addition & 0 deletions src/Campaigns/Blocks/DonateButton/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"default": "Donate now"
}
},
"example": {},
"textdomain": "give",
"render": "file:./render.php"
}
12 changes: 8 additions & 4 deletions src/Campaigns/Factories/CampaignFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

namespace Give\Campaigns\Factories;

use Exception;
use Give\Campaigns\ValueObjects\CampaignGoalType;
use Give\Campaigns\ValueObjects\CampaignStatus;
use Give\Campaigns\ValueObjects\CampaignType;
use Give\DonationForms\Models\DonationForm;
use Give\Framework\Models\Factories\ModelFactory;
use Give\Framework\Support\Facades\DateTime\Temporal;

Expand All @@ -15,10 +17,12 @@ class CampaignFactory extends ModelFactory
{
/**
* @inheritDoc
* @throws Exception
*/
public function definition(): array
{
$currentDate = Temporal::getCurrentDateTime();
$createdAt = Temporal::withoutMicroseconds($currentDate);

return [
'type' => CampaignType::CORE(),
Expand All @@ -27,16 +31,16 @@ public function definition(): array
'title' => __('GiveWP Campaign', 'give'),
'shortDescription' => __('Campaign short description', 'give'),
'longDescription' => __('Campaign long description', 'give'),
'goal' => 10000000,
'goal' => 5000,
'goalType' => CampaignGoalType::AMOUNT(),
'status' => CampaignStatus::ACTIVE(),
'logo' => '',
'image' => '',
'primaryColor' => '#28C77B',
'secondaryColor' => '#FFA200',
'createdAt' => Temporal::withoutMicroseconds($currentDate),
'startDate' => Temporal::withoutMicroseconds($currentDate),
'endDate' => Temporal::withoutMicroseconds($currentDate->modify('+1 day')),
'createdAt' => $createdAt,
'startDate' => $createdAt,
'endDate' => null,
];
}
}
15 changes: 13 additions & 2 deletions src/Campaigns/Repositories/CampaignRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,21 @@ class CampaignRepository
* @unreleased
*/
public function getById(int $id)
{
return $this->queryById($id)->get();
}

/**
* @unreleased
*
* Query Campaign by ID
*
* @unreleased
*/
public function queryById(int $id): ModelQueryBuilder
{
return $this->prepareQuery()
->where('id', $id)
->get();
->where('id', $id);
}

/**
Expand Down
6 changes: 5 additions & 1 deletion src/Campaigns/Routes/GetCampaignsListTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,11 @@ private function getWhereConditions(QueryBuilder $query): QueryBuilder
}
}

if ($status && 'any' !== $status) {
if ($status === 'any') {
$query->whereNotLike('status', 'archived');
} elseif ($status === 'inactive') {
$query->where('status', 'archived');
} elseif ($status) {
$query->where('status', $status);
}

Expand Down
6 changes: 6 additions & 0 deletions src/Donations/DataTransferObjects/DonationQueryData.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,15 @@ final class DonationQueryData
* @var string|null
*/
public $honorific;
/**
* @var int
*/
public $campaignId;

/**
* Convert data from object to Donation
*
* @unreleased Added campaignId property
* @since 3.9.0 Add support for "phone" property
* @since 3.2.0 add fallback for donation mode
* @since 2.23.0 remove parentId property
Expand Down Expand Up @@ -191,6 +196,7 @@ public static function fromObject($donationQueryObject): self
->getKeyAsCamelCase()};
$self->comment = $donationQueryObject->{DonationMetaKeys::COMMENT()
->getKeyAsCamelCase()};
$self->campaignId = (int)$donationQueryObject->{DonationMetaKeys::CAMPAIGN_ID()->getKeyAsCamelCase()};

if (!empty($donationQueryObject->{DonationMetaKeys::SUBSCRIPTION_INITIAL_DONATION()->getKeyAsCamelCase()})) {
$self->type = DonationType::SUBSCRIPTION();
Expand Down
3 changes: 3 additions & 0 deletions src/Donations/Factories/DonationFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Give\Donations\Factories;

use Exception;
use Give\Campaigns\Models\Campaign;
use Give\Donations\ValueObjects\DonationMode;
use Give\Donations\ValueObjects\DonationStatus;
use Give\Donations\ValueObjects\DonationType;
Expand All @@ -15,6 +16,7 @@ class DonationFactory extends ModelFactory
{

/**
* @unreleased added campaignId
* @since 2.22.0 add optional support for anonymous and company properties
* @since 2.20.0 update default donorId to create factory
* @since 2.19.6
Expand All @@ -33,6 +35,7 @@ public function definition(): array
'firstName' => $this->faker->firstName,
'lastName' => $this->faker->lastName,
'email' => $this->faker->email,
'campaignId' => 1,
'formId' => 1,
'formTitle' => 'Form Title',
'anonymous' => $this->faker->optional(0.5, false)->boolean(true),
Expand Down
4 changes: 3 additions & 1 deletion src/Donations/Models/Donation.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
* @since 2.19.6
*
* @property int $id
* @property int $campaignId
* @property int $formId
* @property string $formTitle
* @property DateTime $createdAt
Expand Down Expand Up @@ -69,6 +70,7 @@ class Donation extends Model implements ModelCrud, ModelHasFactory
*/
protected $properties = [
'id' => 'int',
'campaignId' => 'int',
'formId' => 'int',
'formTitle' => 'string',
'purchaseKey' => 'string',
Expand Down Expand Up @@ -194,7 +196,7 @@ public function subscription(): ModelQueryBuilder
*/
public function campaign(): ModelQueryBuilder
{
return give()->campaigns->queryByFormId($this->formId);
return give()->campaigns->queryById($this->campaignId);
}

/**
Expand Down
7 changes: 5 additions & 2 deletions src/Donations/Repositories/DonationRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ public function delete(Donation $donation): bool
}

/**
* @unreleased added campaignId
* @since 3.9.0 Added meta for phone property
* @since 3.2.0 added meta for honorific property
* @since 2.20.0 update amount to use new type, and add currency and exchange rate
Expand Down Expand Up @@ -352,10 +353,12 @@ private function getCoreDonationMetaForDatabase(Donation $donation): array
),
DonationMetaKeys::DONOR_IP => $donation->donorIp ?? give_get_ip(),
DonationMetaKeys::LEVEL_ID => $donation->levelId,
DonationMetaKeys::ANONYMOUS => (int)$donation->anonymous
DonationMetaKeys::ANONYMOUS => (int)$donation->anonymous,
DonationMetaKeys::CAMPAIGN_ID => $donation->campaignId,
];

if ($campaign = $donation->campaign) {
// If the donation is not associated with a campaign, try to find the campaign ID by the form ID
if (!$donation->campaignId && $campaign = give()->campaigns->getByFormId($donation->formId)) {
$meta[DonationMetaKeys::CAMPAIGN_ID] = $campaign->id;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@ final class AssignDuplicatedFormToCampaignTest extends TestCase
public function testDuplicatedFormIsAssignedToCampaign()
{
$campaign = Campaign::factory()->create();
$form = DonationForm::factory()->create();
$form = DonationForm::find($campaign->defaultFormId);

$db = DB::table('give_campaign_forms');
$db->insert(['form_id' => $form->id, 'campaign_id' => $campaign->id]);

// See give/src/DonationForms/V2/Endpoints/FormActions.php:131
require_once(GIVE_PLUGIN_DIR . '/includes/admin/forms/class-give-form-duplicator.php');
Expand Down
Loading

0 comments on commit a1db6f8

Please sign in to comment.