| @@ -37,9 +37,11 @@ | ||
| 37 | 37 | array( $this, 'apply_submit_macros' ) |
| 38 | 38 | ); |
| 39 | 39 | add_filter( |
| 40 | 40 | 'jet-form-builder/rich-content', |
| 41 | - array( $this, 'apply_dynamic_preset' ) | |
| 41 | + array( $this, 'apply_dynamic_preset' ), | |
| 42 | + 10, | |
| 43 | + 4 | |
| 42 | 44 | ); |
| 43 | 45 | add_filter( |
| 44 | 46 | 'jet-form-builder/rich-content', |
| 45 | 47 | array( $this, 'apply_shortcodes' ) |
| @@ -64,14 +66,77 @@ | ||
| 64 | 66 | public static function rich( string $value ): string { |
| 65 | 67 | return apply_filters( 'jet-form-builder/rich-content', $value ); |
| 66 | 68 | } |
| 67 | 69 | |
| 70 | + /** | |
| 71 | + * Same macros/preset/shortcodes pipeline as rich(), but for a value that | |
| 72 | + * is provably admin-authored - a block attribute stored in the form's | |
| 73 | + * own post content, never a value submitted with the request. Declares | |
| 74 | + * the preset trusted, so an explicit `restricted: false` saved through | |
| 75 | + * the field's own "Restrict access" toggle is honoured, the same way it | |
| 76 | + * already is for validation rules, date limits, conditions and dynamic | |
| 77 | + * value. See Preset_Manager::get_field_value() and | |
| 78 | + * jet_fb_parse_dynamic_trusted() for the same distinction elsewhere. | |
| 79 | + * | |
| 80 | + * The regular dynamic-preset callback stays registered in its original | |
| 81 | + * position on the shared filter. Filter arguments identify this invocation | |
| 82 | + * and its exact original content, preserving the established macros -> | |
| 83 | + * preset -> shortcodes order without mutable hook state. If macros change | |
| 84 | + * the content, its result is parsed as untrusted request-derived data. | |
| 85 | + * | |
| 86 | + * @param string $value | |
| 87 | + * | |
| 88 | + * @return string | |
| 89 | + */ | |
| 90 | + public function rich_trusted( string $value ): string { | |
| 91 | + return apply_filters( 'jet-form-builder/rich-content', $value, true, $value ); | |
| 92 | + } | |
| 93 | + | |
| 94 | + /** | |
| 95 | + * Runs macros and shortcodes while deliberately skipping dynamic presets. | |
| 96 | + * Kept as a filter argument rather than removing/re-adding the callback so | |
| 97 | + * its position and accepted-arguments count never change for later calls. | |
| 98 | + * | |
| 99 | + * @param string $value | |
| 100 | + * | |
| 101 | + * @return string | |
| 102 | + */ | |
| 103 | + public function rich_without_preset( string $value ): string { | |
| 104 | + return apply_filters( 'jet-form-builder/rich-content', $value, false, '', true ); | |
| 105 | + } | |
| 106 | + | |
| 68 | 107 | public function apply_submit_macros( string $content ): string { |
| 69 | 108 | return $this->get_parser()->parse_macros( $content ); |
| 70 | 109 | } |
| 71 | 110 | |
| 72 | - public function apply_dynamic_preset( string $content ): string { | |
| 111 | + public function apply_dynamic_preset( | |
| 112 | + string $content, | |
| 113 | + bool $trusted = false, | |
| 114 | + string $trusted_content = '', | |
| 115 | + bool $without_preset = false | |
| 116 | + ): string { | |
| 117 | + if ( $without_preset ) { | |
| 118 | + return $content; | |
| 119 | + } | |
| 120 | + | |
| 121 | + // Macros execute before this callback and can expand request-controlled | |
| 122 | + // values. A trusted parse is safe only when the content is still the | |
| 123 | + // exact admin-authored string passed to rich_trusted(). | |
| 124 | + if ( $trusted && $content === $trusted_content ) { | |
| 125 | + return $this->apply_dynamic_preset_trusted( $content ); | |
| 126 | + } | |
| 127 | + | |
| 73 | 128 | return Tools::to_string( $this->get_dynamic_preset()->parse_json( $content ) ); |
| 129 | + } | |
| 130 | + | |
| 131 | + public function apply_dynamic_preset_trusted( string $content ): string { | |
| 132 | + // Do not use get_dynamic_preset(): it is shared by ordinary rich() calls. | |
| 133 | + // A preset-sanitize callback may make a nested ordinary call while this | |
| 134 | + // source is resolving, so the trusted origin must be invocation-local. | |
| 135 | + $preset = new Dynamic_Preset(); | |
| 136 | + $preset->trust_restriction_flag( true ); | |
| 137 | + | |
| 138 | + return Tools::to_string( $preset->parse_json( $content ) ); | |
| 74 | 139 | } |
| 75 | 140 | |
| 76 | 141 | public function apply_shortcodes( string $content ): string { |
| 77 | 142 | return do_shortcode( $content ); |