← All changes
|
includes/shortcodes/class-charitable-stat-shortcode.php
+130
-8
1.7.0.12
→
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; |