PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.17.0
GiveWP – Donation Plugin and Fundraising Platform v4.17.0
4.17.0 4.16.9 4.16.8.1 4.16.8 4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 All 256 releases
← All changes | src/Campaigns/Actions/AllowGiveRolesToEditCampaignPages.php +18 -4 4.15.1 → 4.17.0 View file →
@@ -2,8 +2,9 @@
2 2
3 3 namespace Give\Campaigns\Actions;
4 4
5 5 use Give\Campaigns\ValueObjects\CampaignPageMetaKeys;
6 +use Give\Framework\Database\DB;
6 7 use WP_User;
7 8
8 9 /**
9 10 * Allow users with Give roles to edit and publish campaign landing pages.
@@ -29,15 +30,16 @@
29 30 * Filter meta capabilities for campaign pages.
30 31 *
31 32 * Hooked to 'map_meta_cap' filter.
32 33 *
34 + * @since 4.15.3 Handle null $cap gracefully for better compatibility.
33 35 * @since 4.14.0
34 36 */
35 - public function mapMetaCap(array $caps, string $cap, int $userId, array $args): array
37 + public function mapMetaCap(array $caps, ?string $cap, int $userId, array $args): array
36 38 {
37 39 // Fast check: only handle specific meta capabilities
38 40 static $pageMetaCaps = ['edit_post' => true, 'delete_post' => true, 'publish_post' => true, 'read_post' => true];
39 - if (!isset($pageMetaCaps[$cap])) {
41 + if (!is_string($cap) || !isset($pageMetaCaps[$cap])) {
40 42 return $caps;
41 43 }
42 44
43 45 // We need a post ID to check
@@ -111,8 +113,9 @@
111 113
112 114 /**
113 115 * Check if a post is a campaign page (with caching).
114 116 *
117 + * @since 4.16.7 Read the campaign ID meta directly instead of through get_post_meta().
115 118 * @since 4.14.0
116 119 */
117 120 private function isCampaignPage(int $postId): bool
118 121 {
@@ -122,13 +125,24 @@
122 125
123 126 $post = get_post($postId);
124 127 if (!$post || $post->post_type !== 'page') {
125 128 self::$campaignPageCache[$postId] = false;
129 +
126 130 return false;
127 131 }
128 132
129 - $campaignId = get_post_meta($postId, CampaignPageMetaKeys::CAMPAIGN_ID, true);
130 - self::$campaignPageCache[$postId] = !empty($campaignId);
133 + /*
134 + * get_post_meta() fires the get_post_metadata filter, which third parties hook to run
135 + * capability checks. Those re-enter this action through map_meta_cap and recurse until
136 + * the call stack is exhausted, so read the meta without going through the filter.
137 + */
138 + $campaignPageMeta = DB::table('postmeta')
139 + ->select('meta_value')
140 + ->where('post_id', $postId)
141 + ->where('meta_key', CampaignPageMetaKeys::CAMPAIGN_ID)
142 + ->get();
143 +
144 + self::$campaignPageCache[$postId] = !empty($campaignPageMeta->meta_value);
131 145
132 146 return self::$campaignPageCache[$postId];
133 147 }
134 148