PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 2.12.8
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v2.12.8
2.12.8 2.12.7 2.12.6 2.12.5 2.12.4 2.12.3 2.12.2 2.12.1 2.12.0 2.11.1 2.11.0 2.10.1 2.10.0 2.9.1 2.9.0 2.8.2 2.8.1 2.7.0 2.7.1 2.8.0 trunk 0.0.10 0.0.11 0.0.12 0.0.13 All 98 releases
← All changes | inc/form-styling.php +140 -0 2.12.0 → 2.12.8 View file →
@@ -148,8 +148,148 @@
148 148 return 'inherit' !== ( $block_attrs['formTheme'] ?? 'inherit' );
149 149 }
150 150
151 151 /**
152 + * Check if the form has default SureForms styling disabled.
153 + *
154 + * When enabled (via the `_srfm_forms_styling` meta set through REST/MCP, or
155 + * the `srfm_disable_default_styles` filter), the form is rendered without the
156 + * SureForms frontend stylesheets and inline CSS variables so the site's own
157 + * CSS fully controls the form's appearance.
158 + *
159 + * @param int|string $form_id Form post ID.
160 + * @return bool True when default styling is disabled for the form.
161 + * @since 2.12.2
162 + */
163 + public static function is_default_styling_disabled( $form_id ) {
164 + $form_id = absint( $form_id );
165 + if ( ! $form_id ) {
166 + return false;
167 + }
168 +
169 + $form_styling = get_post_meta( $form_id, '_srfm_forms_styling', true );
170 + $disabled = is_array( $form_styling ) && ! empty( $form_styling['disable_default_styles'] );
171 +
172 + /**
173 + * Filters whether SureForms' default frontend styling is disabled for a form.
174 + *
175 + * Lets themes/plugins toggle the unstyled mode programmatically, overriding the
176 + * stored per-form meta. Return true to render the form without SureForms' default
177 + * stylesheets and inline CSS variables.
178 + *
179 + * @param bool $disabled Whether default styling is disabled (from meta).
180 + * @param int $form_id Form post ID.
181 + * @since 2.12.2
182 + */
183 + return (bool) apply_filters( 'srfm_disable_default_styles', $disabled, $form_id );
184 + }
185 +
186 + /**
187 + * Check whether the SureForms frontend stylesheets can be skipped for a post.
188 + *
189 + * Returns true only when every SureForms form found on the post has default
190 + * styling disabled. When the forms on the post cannot be determined, the
191 + * stylesheets are kept as the safe default.
192 + *
193 + * @param \WP_Post $post Post being rendered.
194 + * @return bool True when the frontend stylesheets can be skipped.
195 + * @since 2.12.2
196 + */
197 + public static function should_skip_frontend_styles( $post ) {
198 + if ( SRFM_FORMS_POST_TYPE === $post->post_type ) {
199 + $form_ids = [ $post->ID ];
200 + } else {
201 + $form_ids = self::get_form_ids_from_content( $post->post_content );
202 + }
203 +
204 + if ( empty( $form_ids ) ) {
205 + return false;
206 + }
207 +
208 + foreach ( $form_ids as $form_id ) {
209 + if ( ! self::is_default_styling_disabled( $form_id ) ) {
210 + return false;
211 + }
212 + }
213 +
214 + return true;
215 + }
216 +
217 + /**
218 + * Extract SureForms form IDs from post content.
219 + *
220 + * Looks for srfm/form blocks (including nested ones) and [sureforms]
221 + * shortcodes.
222 + *
223 + * @param string $content Post content.
224 + * @return array<int> Unique form IDs found in the content.
225 + * @since 2.12.2
226 + */
227 + public static function get_form_ids_from_content( $content ) {
228 + $form_ids = [];
229 +
230 + // Also parse when the content embeds reusable/synced patterns (core/block
231 + // refs) — a form inside a pattern appears as wp:block {"ref":N}, which
232 + // has_block( 'srfm/form' ) alone would never see.
233 + if ( has_block( 'srfm/form', $content ) || has_block( 'core/block', $content ) ) {
234 + $visited_refs = [];
235 + $form_ids = self::collect_form_block_ids( parse_blocks( $content ), $visited_refs );
236 + }
237 +
238 + if ( has_shortcode( $content, 'sureforms' ) && preg_match_all( '/' . get_shortcode_regex( [ 'sureforms' ] ) . '/', $content, $matches ) ) {
239 + foreach ( $matches[3] as $atts_string ) {
240 + $atts = shortcode_parse_atts( $atts_string );
241 + if ( is_array( $atts ) && ! empty( $atts['id'] ) ) {
242 + $form_ids[] = absint( $atts['id'] );
243 + }
244 + }
245 + }
246 +
247 + return array_values( array_unique( array_filter( $form_ids ) ) );
248 + }
249 +
250 + /**
251 + * Recursively collect form IDs from parsed srfm/form blocks, following
252 + * reusable/synced pattern references (core/block) into their wp_block posts.
253 + *
254 + * @param array<mixed> $blocks Parsed blocks from parse_blocks().
255 + * @param array<int, true> $visited_refs Reusable-block post IDs already expanded,
256 + * keyed by ID — guards against reference cycles.
257 + * @return array<int> Form IDs found in srfm/form blocks.
258 + * @since 2.12.2
259 + */
260 + private static function collect_form_block_ids( $blocks, &$visited_refs = [] ) {
261 + $form_ids = [];
262 +
263 + foreach ( $blocks as $block ) {
264 + if ( ! is_array( $block ) ) {
265 + continue;
266 + }
267 + $attrs = isset( $block['attrs'] ) && is_array( $block['attrs'] ) ? $block['attrs'] : [];
268 + if ( isset( $block['blockName'] ) && 'srfm/form' === $block['blockName'] && ! empty( $attrs['id'] ) && is_scalar( $attrs['id'] ) ) {
269 + $form_ids[] = absint( $attrs['id'] );
270 + }
271 + // Reusable/synced pattern: expand the referenced wp_block post so a
272 + // form living inside a pattern is detected like an inline block.
273 + if ( isset( $block['blockName'] ) && 'core/block' === $block['blockName'] && ! empty( $attrs['ref'] ) && is_scalar( $attrs['ref'] ) ) {
274 + $ref = absint( $attrs['ref'] );
275 + if ( $ref && ! isset( $visited_refs[ $ref ] ) ) {
276 + $visited_refs[ $ref ] = true;
277 + $ref_post = get_post( $ref );
278 + if ( $ref_post instanceof \WP_Post && 'wp_block' === $ref_post->post_type && 'publish' === $ref_post->post_status && '' !== $ref_post->post_content ) {
279 + $form_ids = array_merge( $form_ids, self::collect_form_block_ids( parse_blocks( $ref_post->post_content ), $visited_refs ) );
280 + }
281 + }
282 + }
283 + if ( ! empty( $block['innerBlocks'] ) && is_array( $block['innerBlocks'] ) ) {
284 + $form_ids = array_merge( $form_ids, self::collect_form_block_ids( $block['innerBlocks'], $visited_refs ) );
285 + }
286 + }
287 +
288 + return $form_ids;
289 + }
290 +
291 + /**
152 292 * Map dimension block attributes (Top/Right/Bottom/Left/Unit) to form styling.
153 293 *
154 294 * @param array<string,mixed> $form_styling Form styling array.
155 295 * @param array<string,mixed> $block_attrs Block attributes.