← 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 | |