PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.8.13
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.8.13
1.8.13 1.8.12.3 1.8.12.2 1.8.12.1 1.8.12 1.8.11.3 1.8.11.2 1.8.11.1 1.8.11 1.6.6 1.6.60 1.6.7 1.6.8 1.6.9 1.7.0 1.7.0.1 1.7.0.11 1.7.0.12 1.7.0.14 1.7.0.2 1.7.0.3 1.7.0.5 1.7.0.6 1.7.0.7 1.7.0.9 All 211 releases
← All changes | includes/shortcodes/class-charitable-stat-shortcode.php +130 -8 1.7.0.14 → 1.8.13 View file →
@@ -3,9 +3,9 @@
3 3 * Responsible for parsing and displaying the output of the [charitable_stat] shortcode.
4 4 *
5 5 * @package Charitable_Stat/Classes/Charitable_Stat_Shortcode
6 6 * @author David Bisset
7 - * @copyright Copyright (c) 2022, WP Charitable LLC
7 + * @copyright Copyright (c) 2023, WP Charitable LLC
8 8 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9 9 * @since 1.6.0
10 10 * @version 1.6.0
11 11 */
@@ -102,9 +102,11 @@
102 102
103 103 /**
104 104 * Parse shortcode attributes.
105 105 *
106 - * @since 1.6.0
106 + * @since 1.6.0
107 + * @version 1.8.3.5 added 'campaign_categories' to the shortcode attributes.
108 + * @version 1.9.0 added 'include_children' to the shortcode attributes.
107 109 *
108 110 * @param array $atts User-defined attributes.
109 111 * @return array
110 112 */
@@ -109,16 +111,44 @@
109 111 * @return array
110 112 */
111 113 private function parse_args( $atts ) {
112 114 $defaults = array(
113 - 'display' => 'total',
114 - 'campaigns' => '',
115 - 'goal' => false,
115 + 'display' => 'total',
116 + 'campaigns' => '',
117 + 'goal' => false,
118 + 'campaign_categories' => '',
119 + 'include_children' => false,
116 120 );
117 121
118 - $args = shortcode_atts( $defaults, $atts, 'charitable_stat' );
122 + $args = shortcode_atts( $defaults, $atts, 'charitable_stat' );
123 +
124 + if ( '' !== $args['campaign_categories'] ) {
125 + $campaign_categories = str_replace( ', ', ',', $args['campaign_categories'] );
126 + $campaign_categories = explode( ',', $args['campaign_categories'] );
127 + $cat_args = [
128 + 'post_type' => 'campaign',
129 + 'posts_per_page' => -1,
130 + 'fields' => 'ids',
131 + 'tax_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
132 + [
133 + 'taxonomy' => 'campaign_category',
134 + 'field' => 'slug',
135 + 'terms' => $campaign_categories,
136 + ],
137 + ],
138 + ];
139 + $cat_query = new WP_Query( $cat_args );
140 + if ( ! empty( $cat_query->posts ) ) {
141 + $campaigns = $cat_query->posts;
142 + $args['campaigns'] = implode( ',', $campaigns );
143 + }
144 + }
145 +
119 146 $args['campaigns'] = strlen( $args['campaigns'] ) ? explode( ',', $args['campaigns'] ) : array();
120 147
148 + // Convert include_children to boolean.
149 + $args['include_children'] = filter_var( $args['include_children'], FILTER_VALIDATE_BOOLEAN );
150 +
121 151 return $args;
122 152 }
123 153
124 154 /**
@@ -135,17 +165,109 @@
135 165 /**
136 166 * Return the arguments used for generating the report.
137 167 *
138 168 * @since 1.6.0
169 + * @version 1.9.0 added support for including child campaigns.
139 170 *
140 171 * @return array
141 172 */
142 173 private function get_report_args() {
143 174 $args = array();
144 - $args['report_type'] = in_array( $this->type, array( 'progress', 'total' ) ) ? 'amount' : $this->type;
145 - $args['campaigns'] = $this->args['campaigns'];
175 + $args['report_type'] = in_array( $this->type, array( 'progress', 'total' ), true ) ? 'amount' : $this->type;
146 176
177 + // Expand campaigns to include child campaigns if requested.
178 + if ( $this->args['include_children'] && ! empty( $this->args['campaigns'] ) ) {
179 + $args['campaigns'] = $this->expand_campaigns_with_children( $this->args['campaigns'] );
180 + } else {
181 + $args['campaigns'] = $this->args['campaigns'];
182 + }
183 +
147 184 return $args;
185 + }
186 +
187 + /**
188 + * Expand campaign IDs to include all child campaigns recursively.
189 + *
190 + * @since 1.9.0
191 + *
192 + * @param array $campaign_ids Array of campaign IDs.
193 + * @return array Expanded array of campaign IDs including children.
194 + */
195 + private function expand_campaigns_with_children( $campaign_ids ) {
196 + $all_campaign_ids = array();
197 +
198 + foreach ( $campaign_ids as $campaign_id ) {
199 + $campaign_id = intval( $campaign_id );
200 + if ( ! $campaign_id ) {
201 + continue;
202 + }
203 +
204 + // Add the parent campaign.
205 + $all_campaign_ids[] = $campaign_id;
206 +
207 + // Get child campaigns recursively.
208 + $child_campaigns = $this->get_all_child_campaigns( $campaign_id );
209 + if ( ! empty( $child_campaigns ) ) {
210 + $all_campaign_ids = array_merge( $all_campaign_ids, $child_campaigns );
211 + }
212 + }
213 +
214 + return array_unique( array_filter( $all_campaign_ids ) );
215 + }
216 +
217 + /**
218 + * Get all child campaigns for a campaign ID, recursively.
219 + *
220 + * @since 1.9.0
221 + *
222 + * @param int $campaign_id The parent campaign ID.
223 + * @return array Array of child campaign IDs.
224 + */
225 + private function get_all_child_campaigns( $campaign_id ) {
226 + $child_campaign_ids = array();
227 +
228 + // Check if Charitable Ambassadors is active and use its method if available.
229 + if ( class_exists( 'Charitable_Ambassadors_Campaign' ) ) {
230 + $ambassadors_campaign = new Charitable_Ambassadors_Campaign( $campaign_id );
231 + $child_campaigns = $ambassadors_campaign->get_child_campaigns();
232 +
233 + if ( ! empty( $child_campaigns ) ) {
234 + $child_campaign_ids = array_merge( $child_campaign_ids, $child_campaigns );
235 +
236 + // Recursively get grandchildren.
237 + foreach ( $child_campaigns as $child_id ) {
238 + $grandchildren = $this->get_all_child_campaigns( $child_id );
239 + if ( ! empty( $grandchildren ) ) {
240 + $child_campaign_ids = array_merge( $child_campaign_ids, $grandchildren );
241 + }
242 + }
243 + }
244 + } else {
245 + // Fallback to standard WordPress parent-child relationship.
246 + $direct_children = get_posts(
247 + array(
248 + 'post_type' => Charitable::CAMPAIGN_POST_TYPE,
249 + 'posts_per_page' => -1,
250 + 'post_parent' => $campaign_id,
251 + 'fields' => 'ids',
252 + 'post_status' => 'any',
253 + )
254 + );
255 +
256 + if ( ! empty( $direct_children ) ) {
257 + $child_campaign_ids = array_merge( $child_campaign_ids, $direct_children );
258 +
259 + // Recursively get grandchildren.
260 + foreach ( $direct_children as $child_id ) {
261 + $grandchildren = $this->get_all_child_campaigns( $child_id );
262 + if ( ! empty( $grandchildren ) ) {
263 + $child_campaign_ids = array_merge( $child_campaign_ids, $grandchildren );
264 + }
265 + }
266 + }
267 + }
268 +
269 + return $child_campaign_ids;
148 270 }
149 271 }
150 272
151 273 endif;