PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.7.0.6
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.7.0.6
1.8.13.1 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 All 212 releases
charitable / includes / abstracts / abstract-class-charitable-admin-actions.php

abstract-class-charitable-admin-actions.php in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.7.0.6, at includes/abstracts/abstract-class-charitable-admin-actions.php

397 lines 10.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Registers and performs admin actions.
4 *
5 * @package Charitable/Classes/Charitable_Admin_Actions
6 * @author David Bisset
7 * @copyright Copyright (c) 2022, WP Charitable LLC
8 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9 * @since 1.5.0
10 * @version 1.6.0
11 */
12
13 // Exit if accessed directly.
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16 }
17
18 if ( ! class_exists( 'Charitable_Admin_Actions' ) ) :
19
20 /**
21 * Charitable_Admin_Actions
22 *
23 * @since 1.5.0
24 */
25 abstract class Charitable_Admin_Actions implements Charitable_Admin_Actions_Interface {
26
27 /**
28 * Registered actions.
29 *
30 * @since 1.5.0
31 *
32 * @var array
33 */
34 private $actions;
35
36 /**
37 * Registered groups.
38 *
39 * @since 1.5.0
40 *
41 * @var array
42 */
43 private $groups;
44
45 /**
46 * The result of the most recently executed action.
47 *
48 * @since 1.5.0
49 *
50 * @var int
51 */
52 private $result_message;
53
54 /**
55 * Create class object.
56 *
57 * @since 1.5.0
58 */
59 public function __construct() {
60 $this->actions = array();
61 $this->groups = array(
62 '' => array(),
63 );
64 }
65
66 /**
67 * Return the array of actions.
68 *
69 * @since 1.5.0
70 *
71 * @return array
72 */
73 public function get_actions() {
74 return $this->actions;
75 }
76
77 /**
78 * Get available actions, given an object id and set of arguments.
79 *
80 * @since 1.5.0
81 *
82 * @param int $object_id The object ID. This could be the ID of the donation, campaign, donor, etc.
83 * @param array $args Optional. Mixed set of arguments.
84 * @return array
85 */
86 public function get_available_actions( $object_id, $args = array() ) {
87 $actions = array();
88
89 foreach ( $this->actions as $action => $action_args ) {
90 if ( $this->is_action_available( $action_args, $object_id, $args ) ) {
91 $actions[ $action ] = $action_args;
92 }
93 }
94
95 return $actions;
96 }
97
98 /**
99 * Check if there are any available actions, given an object id and set of arguments.
100 *
101 * @since 1.5.0
102 *
103 * @param int $object_id The object ID. This could be the ID of the donation, campaign, donor, etc.
104 * @param array $args Optional. Mixed set of arguments.
105 * @return boolean
106 */
107 public function has_available_actions( $object_id, $args = array() ) {
108 foreach ( $this->actions as $action => $action_args ) {
109 if ( $this->is_action_available( $action_args, $object_id, $args ) ) {
110 return true;
111 }
112 }
113
114 return false;
115 }
116
117 /**
118 * Add action fields, if there are any.
119 *
120 * @since 1.6.0
121 *
122 * @param int $object_id The current post ID.
123 * @param string $action_id The key of the action.
124 * @return void
125 */
126 public function add_action_fields( $object_id, $action_id ) {
127 if ( ! array_key_exists( $action_id, $this->actions ) ) {
128 return;
129 }
130
131 $action = $this->actions[ $action_id ];
132
133 if ( ! array_key_exists( 'fields', $action ) || ! $action['fields'] ) {
134 return;
135 }
136
137 ob_start();
138
139 call_user_func( $action['fields'], $object_id, $action );
140
141 $fields = ob_get_clean();
142
143 if ( ! $fields ) {
144 return;
145 }
146
147 echo '<div class="charitable-action-fields" style="display: none;" data-type="' . esc_attr( $action_id ) . '">' . $fields . '</div>';
148 }
149
150 /**
151 * Checks whether an action is available.
152 *
153 * @since 1.5.0
154 *
155 * @param array $action_args Action arguments.
156 * @param int $object_id The object ID. This could be the ID of the donation, campaign, donor, etc.
157 * @param array $args Optional. Mixed set of arguments.
158 * @return boolean
159 */
160 protected function is_action_available( $action_args, $object_id, $args = array() ) {
161 if ( ! array_key_exists( 'active_callback', $action_args ) ) {
162 return true;
163 }
164
165 $args['action_args'] = $action_args;
166
167 return call_user_func( $action_args['active_callback'], $object_id, $args );
168 }
169
170 /**
171 * Return the array of groups.
172 *
173 * @since 1.5.0
174 *
175 * @return array
176 */
177 public function get_groups() {
178 return $this->groups;
179 }
180
181 /**
182 * Returns all groups with at least one action available.
183 *
184 * @since 1.5.0
185 *
186 * @param int $object_id The object ID. This could be the ID of the donation, campaign, donor, etc.
187 * @param array $args Optional. Mixed set of arguments.
188 * @return array
189 */
190 public function get_available_groups( $object_id, $args = array() ) {
191 $groups = array();
192
193 foreach ( $this->groups as $group => $actions ) {
194 foreach ( $actions as $action ) {
195 if ( $this->is_action_available( $this->actions[ $action ], $object_id, $args ) ) {
196 $groups[ $group ] = $actions;
197 break;
198 }
199 }
200 }
201
202 return $groups;
203 }
204
205 /**
206 * Get the result message.
207 *
208 * @since 1.5.0
209 *
210 * @param string $location The message location.
211 * @return string
212 */
213 public function show_result_message( $location ) {
214 return add_query_arg( 'message', $this->result_message, $location );
215 }
216
217 /**
218 * Register a new action.
219 *
220 * @since 1.5.0
221 *
222 * @param string $action The action key.
223 * @param array $args {
224 * Array of arguments for the action.
225 *
226 * @type string $label The label to display in the admin.
227 * @type callable $callback A callback function to run when the action is processed.
228 * @type string $button_text Optional. The text to show in the button when this action is selected.
229 * @type callable $active_callback Optional. Any passed callback will receive a donation ID as its only parameter
230 * and should return a boolean result: TRUE if the action should be shown for
231 * the donation; FALSE if it should not.
232 * @type int $success_message Optional. Message to display when an action is successfully run.
233 * @type int $failure_message Optional. Message to display when an action fails to run.
234 * @type callable $fields Optional. Function returning additional fields or content to show when an action is selected.
235 * }
236 * @param string $group Optional. If set, action will be added to a group of other related actions, which will be
237 * shown as an optgroup.
238 * @return boolean True if the action was registerd. False if not.
239 */
240 public function register( $action, $args, $group = 'default' ) {
241 if ( $this->action_exists( $action ) ) {
242 return false;
243 }
244
245 if ( ! $this->action_is_valid( $args ) ) {
246 return false;
247 }
248
249 $this->groups[ $group ] = array_merge( $this->get_group_actions( $group ), array( $action ) );
250 $this->actions[ $action ] = $this->sanitize_action_args( $args );
251
252 return true;
253 }
254
255 /**
256 * Do a particular action.
257 *
258 * @since 1.5.0
259 *
260 * @param string $action The action to do.
261 * @param int $object_id The object ID. This could be the ID of the donation, campaign, donor, etc.
262 * @param array $args Optional. Mixed set of arguments.
263 * @return boolean|WP_Error WP_Error in case of error. Mixed results if the action was performed.
264 */
265 public function do_action( $action, $object_id, $args = array() ) {
266 if ( ! $this->action_exists( $action ) ) {
267 /* translators: %s: action id */
268 return new WP_Error( sprintf( __( 'Action "%s" is not registered.', 'charitable' ), $action ) );
269 }
270
271 $action_args = $this->actions[ $action ];
272
273 if ( ! $this->is_action_available( $action_args, $object_id, $args ) ) {
274 return false;
275 }
276
277 $action_hook = sprintf( 'charitable_%s_admin_action_%s', $this->get_type(), $action );
278
279 /**
280 * Register the action's callback for the hook.
281 */
282 add_filter( $action_hook, $action_args['callback'], 10, 4 );
283
284 /**
285 * Do something for this action and return a boolean result.
286 *
287 * To find the hook for a particular action, you need to know the type of action (i.e. donation, campaign)
288 * and the action key. The hook is constructed like this:
289 *
290 * charitable_{type}_admin_action_{action key}
291 *
292 * @since 1.5.0
293 *
294 * @param boolean $success Whether the action has been successfully completed.
295 * @param int $object_id The object ID. This could be the ID of the donation, campaign, donor, etc.
296 * @param array $args Optional. Mixed set of arguments.
297 * @param string $action The action we are executing.
298 */
299 $success = apply_filters( $action_hook, false, $object_id, $args, $action );
300
301 if ( $success && array_key_exists( 'success_message', $action_args ) ) {
302 $this->result_message = $action_args['success_message'];
303 }
304
305 if ( ! $success && array_key_exists( 'failure_message', $action_args ) ) {
306 $this->result_message = $action_args['failure_message'];
307 }
308
309 if ( isset( $this->result_message ) ) {
310 add_action( 'redirect_post_location', array( $this, 'show_result_message' ) );
311 }
312
313 return $success;
314 }
315
316 /**
317 * Returns a link that will execute a particular action.
318 *
319 * @since 1.5.0
320 *
321 * @param string $action The action to be executed.
322 * @param int $object_id The ID of the object we are executing this action for.
323 * @return string
324 */
325 public function get_action_link( $action, $object_id ) {
326 if ( ! $this->action_exists( $action ) ) {
327 return;
328 }
329
330 return esc_url(
331 add_query_arg(
332 array(
333 'charitable_admin_action' => $action,
334 'action_type' => $this->get_type(),
335 'object_id' => $object_id,
336 '_nonce' => wp_create_nonce( 'donation_action' ),
337 )
338 )
339 );
340 }
341
342 /**
343 * Checks whether a particular action has been registered.
344 *
345 * @since 1.5.0
346 *
347 * @param string $action The action to check.
348 * @return boolean
349 */
350 public function action_exists( $action ) {
351 return array_key_exists( $action, $this->actions );
352 }
353
354 /**
355 * Checks whether an action is valid.
356 *
357 * @since 1.5.9
358 *
359 * @param array $args The action args.
360 * @return boolean
361 */
362 protected function action_is_valid( $args ) {
363 return array_key_exists( 'label', $args ) && array_key_exists( 'callback', $args );
364 }
365
366 /**
367 * Return all of a group's registered actions.
368 *
369 * @since 1.5.9
370 *
371 * @param string $group The group.
372 * @return array
373 */
374 protected function get_group_actions( $group ) {
375 return array_key_exists( $group, $this->groups ) ? $this->groups[ $group ] : array();
376 }
377
378 /**
379 * Sanitize an action args, ensuring that all args exist.
380 *
381 * @since 1.5.9
382 *
383 * @param array $args The action args.
384 * @return array
385 */
386 protected function sanitize_action_args( $args ) {
387 $defaults = array(
388 'button_text' => __( 'Submit', 'charitable' ),
389 'fields' => false,
390 );
391
392 return array_merge( $defaults, $args );
393 }
394 }
395
396 endif;
397