menu_item_parent == $parentId ) { $children = buildHeaderTree( $elements, $element->ID ); if ( $children ) $element->wpse_children = $children; $branch[$element->ID] = $element; unset( $element ); } } return $branch; } function searchSocialMedia($name, $array) { foreach ($array as $key => $val) { if ($val['name'] === $name) { return $key; } } return null; } add_image_size( 'cr_card_thumb', 600, 350 , true); add_image_size( 'cr_large_blog_thumb', 600, 480 , true); // custom excerpt length function wpdocs_custom_excerpt_length( $length ) { return 30; } add_filter( 'excerpt_length', 'wpdocs_custom_excerpt_length', 999 ); function new_excerpt_more( $more ) { return '...'; } add_filter('excerpt_more', 'new_excerpt_more'); (new Theme)->run(); // Force asset URLs to use www to avoid cross-origin script/font blocking. add_filter( 'script_loader_src', function( $src ) { return str_replace( 'https://charityright.org.uk', 'https://www.charityright.org.uk', $src ); } ); add_filter( 'style_loader_src', function( $src ) { return str_replace( 'https://charityright.org.uk', 'https://www.charityright.org.uk', $src ); } ); // Redirect function from author pages add_action('template_redirect', 'my_custom_disable_author_page'); function my_custom_disable_author_page() { global $wp_query; if ( is_author() ) { // Redirect to homepage, set status to 301 permenant redirect. // Function defaults to 302 temporary redirect. wp_redirect(get_option('home'), 301); exit; } } function itsme_disable_feed() { wp_die( __( 'No feed available, please visit the homepage!' ) ); } function disable_attachment_pages() { if (is_attachment()) { // Get the parent post ID $parent_post_id = wp_get_post_parent_id(get_the_ID()); // Redirect to parent post if available, or homepage if not if ($parent_post_id) { wp_redirect(get_permalink($parent_post_id), 301); } else { wp_redirect(home_url(), 301); } exit; } } add_action('template_redirect', 'disable_attachment_pages'); add_action('do_feed', 'itsme_disable_feed', 1); add_action('do_feed_rdf', 'itsme_disable_feed', 1); add_action('do_feed_rss', 'itsme_disable_feed', 1); add_action('do_feed_rss2', 'itsme_disable_feed', 1); add_action('do_feed_atom', 'itsme_disable_feed', 1); add_action('do_feed_rss2_comments', 'itsme_disable_feed', 1); add_action('do_feed_atom_comments', 'itsme_disable_feed', 1); add_action('init', function() { // Add rewrite rule for campaign with query parameter add_rewrite_rule( 'campaigns/([^/]+)/?$', 'index.php?post_type=campaign&name=$matches[1]', 'top' ); // Register your query vars add_filter('query_vars', function($vars) { $vars[] = 'p'; // Using 'p' instead of 'page' return $vars; }); }); // Prevent canonical redirect add_filter('redirect_canonical', function($redirect_url, $requested_url) { if (is_singular('campaign')) { return false; } return $redirect_url; }, 10, 2); // donations add_action('rest_api_init', function () { register_rest_route('charityright/v1', '/donations', [ 'methods' => 'GET', 'callback' => 'get_external_donations', 'permission_callback' => '__return_true', // Adjust permissions if necessary ]); }); if (!function_exists('wp_money_format')) { function wp_money_format($amount, $currency_symbol = '£', $decimal_places = 2, $thousands_separator = ',', $decimal_separator = '.') { // Ensure the amount is a float $amount = floatval($amount); // Format the amount $formatted_amount = number_format($amount, $decimal_places, $decimal_separator, $thousands_separator); // Return with the currency symbol return $currency_symbol . $formatted_amount; } } function get_external_donations($request) { // Define the appeal ID if necessary, otherwise, pass it from the request $appeal_id = $request->get_param('appeal_id'); $page = $request->get_param('page') ?? 1; $per_page = 5; // Define how many donations you want per page // External API URL with the appeal_id $url = trim(str_replace("donate", "", get_field("generic_donate_url", "options")), "/") . "/api/v1/appeal-donations/{$appeal_id}?page={$page}&per_page={$per_page}"; // Fetch donations from the external API $response = wp_remote_get($url); if (is_wp_error($response)) { return new WP_REST_Response([ 'message' => 'Failed to fetch donations from external API', 'error' => $response->get_error_message() ], 500); } $data = json_decode(wp_remote_retrieve_body($response), true); if (!$data || !isset($data['data']) || !is_array($data['data'])) { return new WP_REST_Response([ 'message' => 'No donations found or invalid data format' ], 404); } $formattedDonations = array_map(function($donation) { return [ 'id' => $donation['id'], 'donor_name' => $donation['is_anonymous'] ? 'Anonymous' : $donation['donor_name'], 'initials' => strtoupper(substr($donation['donor_name'], 0, 1)), // Extract initials 'donated_at' => $donation['created_at'], // Pass the raw date, format on frontend 'amount' => $donation['amount'], 'donor_message' => $donation['donor_message'] ?? '' ]; }, $data['data']); // Return formatted donations and pagination info return new WP_REST_Response([ 'donations' => $formattedDonations, 'pagination' => [ 'current_page' => $data['current_page'], 'last_page' => $data['last_page'], 'total' => $data['total'] ] ], 200); } add_action('rest_api_init', function () { register_rest_route('custom/v1', '/delete-post', array( 'methods' => 'DELETE', 'callback' => 'handle_delete_post', 'permission_callback' => '__return_true', 'args' => array( 'slug' => array( 'required' => true, 'validate_callback' => function($param) { return is_string($param); // Ensure slug is a string } ), 'api_key' => array( 'required' => true ) ) )); register_rest_route('custom/v1', '/update-campaign-preview', array( 'methods' => 'POST', 'callback' => 'handle_update_campaign_preview', 'permission_callback' => '__return_true', 'args' => array( 'slug' => array( 'required' => true, 'validate_callback' => function($param) { return is_string($param); // Ensure slug is a string } ), 'api_key' => array( 'required' => true ) ) )); register_rest_route('custom/v1', '/update-strava-leaderboard', array( 'methods' => 'POST', 'callback' => 'handle_strava_leaderboard', 'permission_callback' => '__return_true', 'args' => array( 'api_key' => array( 'required' => true ), 'list' => array( 'required' => false, // Set to true if `list` is mandatory 'validate_callback' => function ($param, $request, $key) { return is_array($param); // Ensure `list` is an array } ) ) )); }); function handle_delete_post($request) { // Validate API key (you should store this securely) $valid_api_key = 'AKDJSHF8932YRJDFKSAFH120'; if ($request['api_key'] !== $valid_api_key) { return new WP_Error( 'invalid_api_key', 'Invalid API key provided.', array('status' => 403) ); } // Get the slug from the request $slug = $request['slug']; // Retrieve the post by slug $post = get_page_by_path($slug, OBJECT, 'campaign'); if (!$post) { return new WP_Error( 'post_not_found', 'Post not found', array('status' => 404) ); } // Attempt to delete the post $deleted = wp_delete_post($post->ID, true); if (!$deleted) { return new WP_Error( 'delete_failed', 'Failed to delete post', array('status' => 500) ); } return array( 'status' => 'success', 'message' => 'Post deleted successfully', 'deleted_slug' => $slug ); } if (!function_exists("number_shorten")) { /** * Shorten long numbers and attaches K, M, B, etc. accordingly * @param int $n * @param int $precision * * @return string */ function number_shorten( $n, $precision = 1 ) { if ($n < 900) { // 0 - 900 $n_format = number_format($n, $precision); $suffix = ''; } else if ($n < 900000) { // 0.9k-850k $n_format = number_format($n / 1000, $precision); $suffix = 'K'; } else if ($n < 900000000) { // 0.9m-850m $n_format = number_format($n / 1000000, $precision); $suffix = 'M'; } else if ($n < 900000000000) { // 0.9b-850b $n_format = number_format($n / 1000000000, $precision); $suffix = 'B'; } else { // 0.9t+ $n_format = number_format($n / 1000000000000, $precision); $suffix = 'T'; } // Remove unecessary zeroes after decimal. "1.0" -> "1"; "1.00" -> "1" // Intentionally does not affect partials, eg "1.50" -> "1.50" if ( $precision > 0 ) { $dotzero = '.' . str_repeat( '0', $precision ); $n_format = str_replace( $dotzero, '', $n_format ); } return $n_format . $suffix; } } function handle_update_campaign_preview ($request){ $existingPost = Etc::findPostByMeta('campaign-preview', 'appeal_id', $request['id']); if ($existingPost) { // Update the existing post $postId = wp_update_post([ 'ID' => $existingPost->ID, 'post_title' => $request['name'], 'post_name' => $request['slug'], 'post_content' => $request['story'], 'post_type' => 'campaign-preview' ]); // Return the updated post object $campaign_preview = get_post($postId); } else { // Create a new post $postId = wp_insert_post([ 'post_title' => $request['name'], 'post_name' => $request['slug'], 'post_content' => $request['story'], 'post_status' => 'publish', 'post_type' => 'campaign-preview' ]); error_log($postId); // Add the custom meta field for appeal_id add_post_meta($postId, 'appeal_id', $request['id']); // Return the newly created post object $campaign_preview = get_post($postId); } $body = $request->get_body(); error_log(print_r(json_decode($body, true), true)); foreach (AppealMapper::toACF(json_decode($body, true)) as $fieldKey => $fieldValue) { update_field($fieldKey, $fieldValue, $campaign_preview); } return $campaign_preview; } function handle_strava_leaderboard (WP_REST_Request $request){ delete_field('strava_leaderboard', 'option'); $list = $request->get_param('list'); if ($list) { foreach ($list as $item) { $row = array( 'athlete_name' => $item['name'], 'athlete_image' => $item['image'], 'distance' => $item['distance'] ); add_row('strava_leaderboard', $row, 'option'); } } else { error_log('No list received.'); } } function ajax_words_of_hope_action_submit() : void{ $email = $_REQUEST[ "email" ]; $name = $_REQUEST[ "name" ]; $school = isset($_REQUEST[ "school" ]) ? $_REQUEST[ "school" ] : null; $form = $_REQUEST[ "form" ]; $address = $_REQUEST[ "address" ]; $message = $_REQUEST[ "message" ]; $us_marketing = isset($_REQUEST[ "us_marketing" ]) ? $_REQUEST[ "us_marketing" ] : null; $uk_marketing = isset($_REQUEST[ "uk_marketing" ]) ? $_REQUEST[ "uk_marketing" ] : null; $is_in_us = $_REQUEST[ "is_in_us" ]; $data = array( 'email' => $email, 'name' => $name, 'school' => $school, 'form' => $form, 'address' => $address, 'message' => $message, 'us_marketing' => $us_marketing !== "on" && $is_in_us, 'uk_marketing' => $uk_marketing == "on" && !$is_in_us, ); // Set up the arguments for the HTTP request $args = array( 'method' => 'POST', 'body' => json_encode($data), 'headers' => array( 'Content-Type' => 'application/json', ), ); $base_url = trim(get_field('generic_donate_url', 'options') ?? 'http://crukv2.test/donate/', '/'); $wohURL = str_replace("/donate", "/api/word-of-hope/store", $base_url); $response = wp_remote_post($wohURL, $args); // Check for errors in the request if (is_wp_error($response)) { $error_message = $response->get_error_message(); error_log("Error making HTTP request: $error_message"); wp_send_json_error(array('message' => 'Error making HTTP request.')); return; } // Check the response from the external API $response_body = wp_remote_retrieve_body($response); $response_code = wp_remote_retrieve_response_code($response); error_log(print_r($response_body, true)); if ($response_code === 201) { // Successfully submitted, return success response wp_send_json_success(array('message' => 'Your message has been successfully submitted.')); } else { // API returned an error, return failure response wp_send_json_error(array('message' => 'There was an error submitting your message.')); } } add_action( "wp_ajax_words_of_hope_action", "ajax_words_of_hope_action_submit" ); add_action( "wp_ajax_nopriv_words_of_hope_action", "ajax_words_of_hope_action_submit" ); // === CR Live Data: Real-time donation updates === add_action('init', function() { \Manza\CharityRight\Endpoints\CacheBust::register(); }); add_action('wp_enqueue_scripts', function() { if (is_singular('campaign')) { wp_enqueue_script('cr-live', get_template_directory_uri() . '/assets/js/cr-live.js', [], '1.0.0', true); } }); // === End CR Live Data === // menu-fix-bust: force cache bust for gute.js add_filter('script_loader_src', function($src, $handle) { if ($handle === 'vl_new_acf_blocks') { $src = add_query_arg('bust', '20260218d', $src); } return $src; }, 10, 2); // === UTM Parameter Forwarding (2026-02-19) === add_action('wp_footer', function() { ?>