PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.8.11.1
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.8.11.1
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 / api / class-charitable-api-route-campaign-css.php

class-charitable-api-route-campaign-css.php in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.8.11.1, at includes/api/class-charitable-api-route-campaign-css.php

267 lines 7.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Sets up the /campaign-css/ API route for serving campaign theme CSS.
4 *
5 * This endpoint serves campaign template CSS with dynamic color values,
6 * avoiding direct PHP file access which can fail on some server configurations.
7 *
8 * @package Charitable/Classes/Charitable_API_Route_Campaign_CSS
9 * @author WP Charitable LLC
10 * @copyright Copyright (c) 2024, WP Charitable LLC
11 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
12 * @since 1.8.9.2
13 * @version 1.8.9.2
14 */
15
16 // Exit if accessed directly.
17 if ( ! defined( 'ABSPATH' ) ) {
18 exit;
19 }
20
21 if ( ! class_exists( 'Charitable_API_Route_Campaign_CSS' ) ) :
22
23 /**
24 * Charitable_API_Route_Campaign_CSS
25 *
26 * @since 1.8.9.2
27 */
28 class Charitable_API_Route_Campaign_CSS extends Charitable_API_Route {
29
30 /**
31 * Route base.
32 *
33 * @since 1.8.9.2
34 *
35 * @var string
36 */
37 protected $base;
38
39 /**
40 * Set up class instance.
41 *
42 * @since 1.8.9.2
43 *
44 * @return void
45 */
46 public function __construct() {
47 parent::__construct();
48
49 $this->base = 'campaign-css';
50 }
51
52 /**
53 * Register the routes for this controller.
54 *
55 * @since 1.8.9.2
56 */
57 public function register_routes() {
58 $args = array(
59 'template' => array(
60 'required' => true,
61 'type' => 'string',
62 'sanitize_callback' => 'sanitize_file_name',
63 'description' => __( 'The campaign template slug (e.g., youth-sports, basic).', 'charitable' ),
64 ),
65 'p' => array(
66 'type' => 'string',
67 'sanitize_callback' => array( $this, 'sanitize_hex_color' ),
68 'description' => __( 'Primary color (hex without #).', 'charitable' ),
69 ),
70 's' => array(
71 'type' => 'string',
72 'sanitize_callback' => array( $this, 'sanitize_hex_color' ),
73 'description' => __( 'Secondary color (hex without #).', 'charitable' ),
74 ),
75 't' => array(
76 'type' => 'string',
77 'sanitize_callback' => array( $this, 'sanitize_hex_color' ),
78 'description' => __( 'Tertiary color (hex without #).', 'charitable' ),
79 ),
80 'b' => array(
81 'type' => 'string',
82 'sanitize_callback' => array( $this, 'sanitize_hex_color' ),
83 'description' => __( 'Button color (hex without #).', 'charitable' ),
84 ),
85 'mw' => array(
86 'type' => 'integer',
87 'sanitize_callback' => 'absint',
88 'default' => 800,
89 'description' => __( 'Mobile breakpoint width in pixels.', 'charitable' ),
90 ),
91 );
92
93 // Frontend CSS route
94 register_rest_route(
95 $this->namespace,
96 '/' . $this->base . '/(?P<template>[a-zA-Z0-9-_]+)',
97 array(
98 'methods' => WP_REST_Server::READABLE,
99 'callback' => array( $this, 'get_campaign_css' ),
100 'permission_callback' => '__return_true', // Public endpoint - CSS needs to be accessible.
101 'args' => $args,
102 )
103 );
104
105 // Admin CSS route (added in 1.8.9.2)
106 register_rest_route(
107 $this->namespace,
108 '/' . $this->base . '-admin/(?P<template>[a-zA-Z0-9-_]+)',
109 array(
110 'methods' => WP_REST_Server::READABLE,
111 'callback' => array( $this, 'get_admin_css' ),
112 'permission_callback' => '__return_true', // Public endpoint - CSS needs to be accessible.
113 'args' => $args,
114 )
115 );
116 }
117
118 /**
119 * Sanitize a hex color value (without the # prefix).
120 *
121 * @since 1.8.9.2
122 *
123 * @param string $color The color value to sanitize.
124 * @return string The sanitized color value.
125 */
126 public function sanitize_hex_color( $color ) {
127 return preg_replace( '/[^A-Fa-f0-9]/', '', $color );
128 }
129
130 /**
131 * Get the campaign CSS for a specific template.
132 *
133 * @since 1.8.9.2
134 *
135 * @param WP_REST_Request $request The API request object.
136 * @return void Outputs CSS directly and exits.
137 */
138 public function get_campaign_css( $request ) {
139 $template = $request->get_param( 'template' );
140
141 // Build the path to the template CSS file.
142 $template_file = charitable()->get_path( 'includes' ) . 'css-templates/frontend/' . $template . '.php';
143
144 // Validate template exists.
145 if ( ! file_exists( $template_file ) ) {
146 status_header( 404 );
147 header( 'Content-Type: text/css; charset=UTF-8' );
148 echo '/* Template not found: ' . esc_html( $template ) . ' */';
149 exit;
150 }
151
152 // Get color parameters with defaults.
153 $primary = $request->get_param( 'p' );
154 $secondary = $request->get_param( 's' );
155 $tertiary = $request->get_param( 't' );
156 $button = $request->get_param( 'b' );
157 $mobile_width = $request->get_param( 'mw' );
158
159 // Set up variables that the template file expects.
160 // These are accessed via $_GET in the original PHP files,
161 // so we'll set them up the same way for compatibility.
162 $_GET['p'] = $primary;
163 $_GET['s'] = $secondary;
164 $_GET['t'] = $tertiary;
165 $_GET['b'] = $button;
166 $_GET['mw'] = $mobile_width;
167
168 // Generate CSS using output buffering.
169 ob_start();
170
171 // Save current working directory.
172 $original_cwd = getcwd();
173
174 // Change to the template directory so relative paths in template files work.
175 chdir( dirname( $template_file ) );
176
177 // Include the template file - it will output CSS.
178 include $template_file;
179
180 // Restore original working directory.
181 chdir( $original_cwd );
182
183 $css = ob_get_clean();
184
185 // Generate ETag for cache validation.
186 $etag = md5( $template . $primary . $secondary . $tertiary . $button . $mobile_width );
187
188 // Set headers for CSS response.
189 header( 'Content-Type: text/css; charset=UTF-8' );
190 header( 'Cache-Control: public, max-age=31536000' ); // 1 year.
191 header( 'ETag: "' . $etag . '"' );
192
193 // Output CSS and exit to prevent REST API from processing further.
194 echo $css;
195 exit;
196 }
197
198 /**
199 * Get the admin CSS for a specific template.
200 *
201 * @since 1.8.9.2
202 *
203 * @param WP_REST_Request $request The API request object.
204 * @return void Outputs CSS directly and exits.
205 */
206 public function get_admin_css( $request ) {
207 $template = $request->get_param( 'template' );
208
209 // Build the path to the admin template CSS file.
210 $template_file = charitable()->get_path( 'includes' ) . 'css-templates/admin/' . $template . '.php';
211
212 // Validate template exists.
213 if ( ! file_exists( $template_file ) ) {
214 status_header( 404 );
215 header( 'Content-Type: text/css; charset=UTF-8' );
216 echo '/* Admin template not found: ' . esc_html( $template ) . ' */';
217 exit;
218 }
219
220 // Get color parameters with defaults.
221 $primary = $request->get_param( 'p' );
222 $secondary = $request->get_param( 's' );
223 $tertiary = $request->get_param( 't' );
224 $button = $request->get_param( 'b' );
225 $mobile_width = $request->get_param( 'mw' );
226
227 // Set up variables that the template file expects.
228 // These are accessed via $_GET in the original PHP files,
229 // so we'll set them up the same way for compatibility.
230 $_GET['p'] = $primary;
231 $_GET['s'] = $secondary;
232 $_GET['t'] = $tertiary;
233 $_GET['b'] = $button;
234 $_GET['mw'] = $mobile_width;
235
236 // Generate CSS using output buffering.
237 ob_start();
238
239 // Save current working directory.
240 $original_cwd = getcwd();
241
242 // Change to the template directory so relative paths in template files work.
243 chdir( dirname( $template_file ) );
244
245 // Include the template file - it will output CSS.
246 include $template_file;
247
248 // Restore original working directory.
249 chdir( $original_cwd );
250
251 $css = ob_get_clean();
252
253 // Generate ETag for cache validation.
254 $etag = md5( 'admin-' . $template . $primary . $secondary . $tertiary . $button . $mobile_width );
255
256 // Set headers for CSS response.
257 header( 'Content-Type: text/css; charset=UTF-8' );
258 header( 'Cache-Control: public, max-age=31536000' ); // 1 year.
259 header( 'ETag: "' . $etag . '"' );
260
261 // Output CSS and exit to prevent REST API from processing further.
262 echo $css;
263 exit;
264 }
265 }
266
267 endif;