PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.7.0.3
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.7.0.3
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
charitable / includes / admin / charitable-core-admin-functions.php

charitable-core-admin-functions.php in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.7.0.3, at includes/admin/charitable-core-admin-functions.php

598 lines 15.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Charitable Core Admin Functions
4 *
5 * General core functions available only within the admin area.
6 *
7 * @package Charitable/Functions/Admin
8 * @version 1.0.0
9 * @author David Bisset
10 * @copyright Copyright (c) 2022, WP Charitable LLC
11 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
12 */
13
14 // Exit if accessed directly.
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit;
17 }
18
19 /**
20 * Load a view from the admin/views folder.
21 *
22 * If the view is not found, an Exception will be thrown.
23 *
24 * Example usage: charitable_admin_view('metaboxes/campaign-title');
25 *
26 * @since 1.0.0
27 *
28 * @param string $view The view to display.
29 * @param array $view_args Optional. Arguments to pass through to the view itself.
30 * @return boolean True if the view exists and was rendered. False otherwise.
31 */
32 function charitable_admin_view( $view, $view_args = array(), $return_html = false ) {
33 $base_path = array_key_exists( 'base_path', $view_args ) ? $view_args['base_path'] : charitable()->get_path( 'admin' ) . 'views/';
34
35 /**
36 * Filter the path to the view.
37 *
38 * @since 1.0.0
39 *
40 * @param string $path The default path.
41 * @param string $view The view.
42 * @param array $view_args View args.
43 */
44 $filename = apply_filters( 'charitable_admin_view_path', $base_path . $view . '.php', $view, $view_args );
45
46 if ( ! is_readable( $filename ) ) {
47 charitable_get_deprecated()->doing_it_wrong(
48 __FUNCTION__,
49 sprintf(
50 /* translators: %s: Filename of passed view */
51 __( 'Passed view (%s) not found or is not readable.', 'charitable' ),
52 $filename
53 ),
54 '1.0.0'
55 );
56
57 return false;
58 }
59
60 ob_start();
61
62 include( $filename );
63
64 if ( $return_html ) {
65 $output = ob_get_contents();
66 ob_end_clean();
67 return $output;
68 }
69
70 ob_end_flush();
71
72 return true;
73 }
74
75 /**
76 * Returns the Charitable_Settings helper.
77 *
78 * @since 1.0.0
79 *
80 * @return Charitable_Settings
81 */
82 function charitable_get_admin_settings() {
83 return Charitable_Settings::get_instance();
84 }
85
86 /**
87 * Returns the Charitable_Admin_Notices helper.
88 *
89 * @since 1.4.6
90 *
91 * @return Charitable_Admin_Notices
92 */
93 function charitable_get_admin_notices() {
94 return charitable()->registry()->get( 'admin_notices' );
95 }
96
97 /**
98 * Returns whether we are currently viewing the Charitable settings area.
99 *
100 * @since 1.2.0
101 *
102 * @param string $tab Optional. If passed, the function will also check that we are on the given tab.
103 * @return boolean
104 */
105 function charitable_is_settings_view( $tab = '' ) {
106 if ( ! empty( $_POST ) ) {
107 $is_settings = array_key_exists( 'option_page', $_POST ) && 'charitable_settings' === $_POST['option_page'];
108
109 if ( ! $is_settings || empty( $tab ) ) {
110 return $is_settings;
111 }
112
113 return array_key_exists( 'charitable_settings', $_POST ) && array_key_exists( $tab, $_POST['charitable_settings'] );
114 }
115
116 $is_settings = isset( $_GET['page'] ) && 'charitable-settings' == $_GET['page'];
117
118 if ( ! $is_settings || empty( $tab ) ) {
119 return $is_settings;
120 }
121
122 /* The general tab can be loaded when tab is not set. */
123 if ( 'general' == $tab ) {
124 return ! isset( $_GET['tab'] ) || 'general' == $_GET['tab'];
125 }
126
127 return isset( $_GET['tab'] ) && $tab == $_GET['tab'];
128 }
129
130 /**
131 * Print out the settings fields for a particular settings section.
132 *
133 * This is based on WordPress' do_settings_fields but allows the possibility
134 * of leaving out a field lable/title, for fullwidth fields.
135 *
136 * @see do_settings_fields
137 *
138 * @since 1.0.0
139 *
140 * @global $wp_settings_fields Storage array of settings fields and their pages/sections
141 *
142 * @param string $page Slug title of the admin page who's settings fields you want to show.
143 * @param string $section Slug title of the settings section who's fields you want to show.
144 * @return string
145 */
146 function charitable_do_settings_fields( $page, $section ) {
147 global $wp_settings_fields;
148
149 if ( ! isset( $wp_settings_fields[ $page ][ $section ] ) ) {
150 return;
151 }
152
153 foreach ( (array) $wp_settings_fields[ $page ][ $section ] as $field ) {
154 $class = '';
155
156 if ( ! empty( $field['args']['class'] ) ) {
157 $class = ' class="' . esc_attr( $field['args']['class'] ) . '"';
158 }
159
160 echo "<tr{$class}>";
161
162 if ( ! empty( $field['args']['label_for'] ) ) {
163 echo '<th scope="row"><label for="' . esc_attr( $field['args']['label_for'] ) . '">' . $field['title'] . '</label></th>';
164 echo '<td>';
165 call_user_func( $field['callback'], $field['args'] );
166 echo '</td>';
167 } elseif ( ! empty( $field['title'] ) ) {
168 echo '<th scope="row">' . $field['title'] . '</th>';
169 echo '<td>';
170 call_user_func( $field['callback'], $field['args'] );
171 echo '</td>';
172 } else {
173 echo '<td colspan="2" class="charitable-fullwidth">';
174 call_user_func( $field['callback'], $field['args'] );
175 echo '</td>';
176 }
177
178 echo '</tr>';
179 }
180 }
181
182 /**
183 * Add new tab to the Charitable settings area.
184 *
185 * @since 1.3.0
186 *
187 * @param string[] $tabs
188 * @param string $key
189 * @param string $name
190 * @param mixed[] $args
191 * @return string[]
192 */
193 function charitable_add_settings_tab( $tabs, $key, $name, $args = array() ) {
194 $defaults = array(
195 'index' => 3,
196 );
197
198 $args = wp_parse_args( $args, $defaults );
199 $keys = array_keys( $tabs );
200 $values = array_values( $tabs );
201
202 array_splice( $keys, $args['index'], 0, $key );
203 array_splice( $values, $args['index'], 0, $name );
204
205 return array_combine( $keys, $values );
206 }
207
208 /**
209 * Return the donation actions class.
210 *
211 * @since 1.5.0
212 *
213 * @return Charitable_Donation_Admin_Actions
214 */
215 function charitable_get_donation_actions() {
216 return Charitable_Admin::get_instance()->get_donation_actions();
217 }
218
219
220 /**
221 * Adds the "Upgrade to Pro" menu item to the very end of the submenu.
222 *
223 * @since 1.7.0
224 */
225 function charitable_add_upgrade_item() {
226 global $submenu;
227
228 if ( charitable_is_pro() ) {
229 return;
230 }
231
232 $submenu['charitable'][99] = array(
233 __( 'Upgrade to Pro', 'chariable' ),
234 'manage_options',
235 charitable_ga_url(
236 'https://wpcharitable.com/lite-vs-pro/',
237 urlencode( 'Admin Menu Link'),
238 urlencode( 'Upgrade to Pro' )
239 )
240 );
241 }
242 add_action('admin_menu', 'charitable_add_upgrade_item');
243
244
245 /**
246 * Outputs "please rate" text.
247 *
248 * @since 1.7.0
249 *
250 * @param string $footer_text Footer text.
251 * @return string
252 */
253 function charitable_add_footer_text( $footer_text ) {
254 if ( ! charitable_is_admin_screen() ) {
255 return $footer_text;
256 }
257
258 return sprintf(
259 /* translators: %1$s Opening strong tag, do not translate. %2$s Closing strong tag, do not translate. %3$s Opening anchor tag, do not translate. %4$s Closing anchor tag, do not translate. */
260 __( 'Please rate %1$sWP Charitable%2$s %3$s�
261 �
262 �
263 �
264 �
265 %4$s on %3$sWordPress.org%4$s to help us spread the word. Thank you from the WP Charitable team!', 'stripe' ),
266 '<strong>',
267 '</strong>',
268 '<a href="https://wordpress.org/support/plugin/charitable/reviews/?filter=5#new-post" rel="noopener noreferrer" target="_blank">',
269 '</a>'
270 );
271 }
272 add_filter( 'admin_footer_text', 'charitable_add_footer_text' );
273
274 /**
275 * Check if a screen is a plugin admin view.
276 * Returns the screen id if true, false (bool) if not.
277 *
278 * @since 1.7.0
279 *
280 * @return string|bool
281 */
282 function charitable_is_admin_screen() {
283 $screen = \get_current_screen();
284
285 if (
286 'charitable' === $screen->post_type ||
287 'campaign' === $screen->post_type ||
288 'charitable' === $screen->parent_file
289 ) {
290 return 'charitable';
291 }
292
293 if ( isset( $_GET['page'] ) ) {
294 if ( 'charitable' == $_GET['page'] ) {
295 return 'charitable';
296 }
297
298 // if ( 'charitable_settings' == $_GET['page'] ) {
299 // return 'charitable_settings';
300 // }
301
302 // if ( 'charitable_system_status' == $_GET['page'] ) {
303 // return 'charitable_system_status';
304 // }
305 }
306
307 return false;
308 }
309
310 /**
311 * Appends UTM parameters to a given URL.
312 *
313 * @since 1.7.0
314 *
315 * @param string $base_url Base URL.
316 * @param string $utm_medium utm_medium parameter.
317 * @param string $utm_content Optional. utm_content parameter.
318 * @return string $url Full Google Analytics campaign URL.
319 */
320 function charitable_ga_url( $base_url, $utm_medium, $utm_content = false ) {
321 /**
322 * Filters the UTM campaign for generated links.
323 *
324 * @since 3.0.0
325 *
326 * @param string $utm_campaign
327 */
328 $utm_campaign = apply_filters( 'charitable_utm_campaign', 'WP+Charitable' );
329
330 $args = array(
331 'utm_source' => 'WordPress',
332 'utm_campaign' => $utm_campaign,
333 'utm_medium' => $utm_medium,
334 );
335
336 if ( ! empty( $utm_content ) ) {
337 $args['utm_content'] = $utm_content;
338 }
339
340 return esc_url( add_query_arg( $args, $base_url ) );
341 }
342
343 /**
344 * URL for upgrading to Pro (or another Pro licecnse).
345 *
346 * @since 1.7.0
347 *
348 * @param string $utm_medium utm_medium parameter.
349 * @param string $utm_content Optional. utm_content parameter.
350 * @return string
351 */
352 function charitable_pro_upgrade_url( $utm_medium, $utm_content = '' ) {
353 return apply_filters(
354 'charitable_upgrade_link',
355 charitable_ga_url(
356 'https://wpcharitable.com/lite-vs-pro/',
357 urlencode( $utm_medium ),
358 urlencode( $utm_content )
359 ),
360 $utm_medium,
361 $utm_content
362 );
363 }
364
365 /**
366 * Get the current installation license type (always lowercase).
367 *
368 * @since 1.7.0.3
369 *
370 * @return string|false
371 */
372 function charitable_get_license_type() {
373
374 $type = charitable_setting( 'type', '', 'charitable_license' );
375
376 if ( empty( $type ) || ! charitable()->is_pro() ) {
377 return false;
378 }
379
380 return strtolower( $type );
381 }
382
383 /**
384 * Get when WPCharitable was first installed.
385 *
386 * @since 1.6.0
387 *
388 * @param string $type Specific install type to check for.
389 *
390 * @return int|false Unix timestamp. False on failure.
391 */
392 function charitable_get_activated_timestamp( $type = '' ) {
393
394 $activated = (array) get_option( 'charitable_activated', [] );
395
396 if ( empty( $activated ) ) {
397 return false;
398 }
399
400 // When a passed install type is empty, then get it from a DB.
401 // If it is installed/activated first, it is saved first.
402 $type = empty( $type ) ? (string) array_keys( $activated )[0] : $type;
403
404 if ( ! empty( $activated[ $type ] ) ) {
405 return absint( $activated[ $type ] );
406 }
407
408 // Fallback.
409 $types = array_diff( [ 'lite', 'pro' ], [ $type ] );
410
411 foreach ( $types as $_type ) {
412 if ( ! empty( $activated[ $_type ] ) ) {
413 return absint( $activated[ $_type ] );
414 }
415 }
416
417 return false;
418 }
419
420 /**
421 * Check permissions for currently logged in user, taken from WPForms.
422 * Both short (e.g. 'view_own_forms') or long (e.g. 'charitable_view_own_forms') capability name can be used.
423 * Only Charitable capabilities get processed.
424 *
425 * @since 1.7.0.3
426 *
427 * @param array|string $caps Capability name(s).
428 * @param int $id ID of the specific object to check against if capability is a "meta" cap. "Meta"
429 * capabilities, e.g. 'edit_post', 'edit_user', etc., are capabilities used by
430 * map_meta_cap() to map to other "primitive" capabilities, e.g. 'edit_posts',
431 * edit_others_posts', etc. Accessed via func_get_args() and passed to
432 * WP_User::has_cap(), then map_meta_cap().
433 *
434 * @return bool
435 */
436 function charitable_current_user_can( $caps = [], $id = 0 ) {
437
438 $user_can = current_user_can( $caps , $id );
439
440 return apply_filters( 'charitable_current_user_can', $user_can, $caps, $id );
441 }
442
443 /**
444 * Determines whether the current request is a WP CLI request.
445 *
446 * @since 1.7.0.3
447 *
448 * @return bool
449 */
450 function charitable_doing_wp_cli() {
451
452 return defined( 'WP_CLI' ) && WP_CLI;
453 }
454
455 /**
456 * Modify the default USer-Agent generated by wp_remote_*() to include additional information.
457 *
458 * @since 1.7.0.3
459 *
460 * @return string
461 */
462 function charitable_get_default_user_agent() {
463
464 $wpcharitable_type = function_exists( 'charitable_is_pro' ) && charitable_is_pro() ? 'Paid' : 'Lite';
465
466 return 'WordPress/' . get_bloginfo( 'version' ) . '; ' . get_bloginfo( 'url' ) . '; WPCharitable/' . $wpcharitable_type;
467 }
468
469
470 function charitable_theme_template_paths() {
471
472 $template_dir = 'charitable';
473
474 $file_paths = array(
475 1 => trailingslashit( get_stylesheet_directory() ) . $template_dir,
476 10 => trailingslashit( get_template_directory() ) . $template_dir,
477 100 => trailingslashit( CHARTIABLE_DIRECTORY_PATH ) . 'includes',
478 );
479
480 $file_paths = apply_filters( 'charitable_helpers_templates_get_theme_template_paths', $file_paths );
481
482 // Sort the file paths based on priority.
483 ksort( $file_paths, SORT_NUMERIC );
484
485 return array_map( 'trailingslashit', $file_paths );
486 }
487
488 /**
489 * Locate a template and return the path for inclusion.
490 *
491 * @since 1.7.0.3
492 *
493 * @param string $template_name Template name.
494 *
495 * @return string
496 */
497 function charitable_locate_template( $template_name ) {
498
499 // Trim off any slashes from the template name.
500 $template_name = ltrim( $template_name, '/' );
501
502 if ( empty( $template_name ) ) {
503 return apply_filters( 'charitable_helpers_templates_locate', '', $template_name );
504 }
505
506 $located = '';
507
508 // Try locating this template file by looping through the template paths.
509 foreach ( charitable_theme_template_paths() as $template_path ) {
510 if ( file_exists( $template_path . $template_name ) ) {
511 $located = $template_path . $template_name;
512 break;
513 }
514 }
515
516 return apply_filters( 'charitable_helpers_templates_locate', $located, $template_name );
517 }
518
519 /**
520 * Include a template.
521 * Use 'require' if $args are passed or 'load_template' if not.
522 *
523 * @since 1.7.0.3
524 *
525 * @param string $template_name Template name.
526 * @param array $args Arguments.
527 * @param bool $extract Extract arguments.
528 *
529 * @throws \RuntimeException If extract() tries to modify the scope.
530 */
531 function charitable_admin_include_html( $template_name, $args = array(), $extract = false ) {
532
533 $template_name .= '.php';
534
535 // Allow 3rd party plugins to filter template file from their plugin.
536 $located = apply_filters( 'charitable_helpers_templates_include_html_located', charitable_locate_template( $template_name ), $template_name, $args, $extract );
537 $args = apply_filters( 'charitable_helpers_templates_include_html_args', $args, $template_name, $extract );
538
539 if ( empty( $located ) || ! \is_readable( $located ) ) {
540 return;
541 }
542
543 // Load template WP way if no arguments were passed.
544 if ( empty( $args ) ) {
545 load_template( $located, false );
546 return;
547 }
548
549 $extract = apply_filters( 'charitable_helpers_templates_include_html_extract_args', $extract, $template_name, $args );
550
551 if ( $extract && is_array( $args ) ) {
552
553 $created_vars_count = extract( $args, EXTR_SKIP ); // phpcs:ignore WordPress.PHP.DontExtract
554
555 // Protecting existing scope from modification.
556 if ( count( $args ) !== $created_vars_count ) {
557 throw new \RuntimeException( 'Extraction failed: variable names are clashing with the existing ones.' );
558 }
559 }
560
561 require $located;
562 }
563
564 /**
565 * Like self::include_html, but returns the HTML instead of including.
566 *
567 * @since 1.7.0.3
568 *
569 * @param string $template_name Template name.
570 * @param array $args Arguments.
571 * @param bool $extract Extract arguments.
572 *
573 * @return string
574 */
575 function charitable_admin_get_html( $template_name, $args = array(), $extract = false ) {
576 ob_start();
577 charitable_admin_include_html( $template_name, $args, $extract );
578 return ob_get_clean();
579 }
580
581 /**
582 * Include a template - alias to \charitable\Helpers\Template::get_html.
583 * Use 'require' if $args are passed or 'load_template' if not.
584 *
585 * @since 1.7.0.3
586 *
587 * @param string $template_name Template name.
588 * @param array $args Arguments.
589 * @param bool $extract Extract arguments.
590 *
591 * @throws \RuntimeException If extract() tries to modify the scope.
592 *
593 * @return string Compiled HTML.
594 */
595 function charitable_render( $template_name, $args = array(), $extract = false ) {
596 return charitable_admin_get_html( $template_name, $args, $extract );
597 }
598