PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 3.4.0
JetFormBuilder — Dynamic Blocks Form Builder v3.4.0
3.6.3.1 3.6.3 3.6.2.2 3.6.2.1 3.6.2 3.6.1.1 3.6.1 3.6.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.1.0 2.1.1 2.1.10 2.1.11 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 3.0.0 3.0.0.1 3.0.0.2 3.0.0.3 3.0.1 3.0.1.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.0.1 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.3.1 3.3.4 3.3.4.1 3.3.4.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.5.1 3.4.5.2 3.4.6 3.4.7 3.4.7.1 3.5.0 3.5.1 3.5.1.1 3.5.1.2 3.5.2 3.5.2.1 3.5.3 3.5.4 3.5.5 3.5.6 3.5.6.1 3.5.6.2 3.5.6.3 3.6.0
jetformbuilder / modules / captcha / module.php
jetformbuilder / modules / captcha Last commit date
abstract-captcha 2 years ago admin-tabs 2 years ago assets 1 year ago block-types 2 years ago blocks-metadata 2 years ago friendly-captcha 2 years ago hcaptcha 2 years ago re-captcha-v3 2 years ago turnstile 2 years ago .eslintrc.js 1 year ago module.php 2 years ago
module.php
396 lines
1 <?php
2
3
4 namespace JFB_Modules\Captcha;
5
6 // If this file is called directly, abort.
7 if ( ! defined( 'WPINC' ) ) {
8 die;
9 }
10
11 use Jet_Form_Builder\Admin\Tabs_Handlers\Tab_Handler_Manager;
12 use Jet_Form_Builder\Blocks\Block_Helper;
13 use Jet_Form_Builder\Blocks\Exceptions\Render_Empty_Field;
14 use JFB_Components\Repository\Repository_Pattern_Trait;
15 use Jet_Form_Builder\Classes\Tools;
16 use Jet_Form_Builder\Exceptions\Repository_Exception;
17 use JFB_Modules\Captcha\Abstract_Captcha\Base_Captcha;
18 use JFB_Modules\Captcha\Abstract_Captcha\Captcha_Frontend_Style_It;
19 use JFB_Modules\Captcha\Abstract_Captcha\Captcha_Separate_Editor_Script;
20 use JFB_Modules\Captcha\Abstract_Captcha\Captcha_Separate_Frontend_Script;
21 use JFB_Modules\Captcha\Abstract_Captcha\Captcha_Settings_From_Options;
22 use JFB_Modules\Captcha\Friendly_Captcha\Friendly_Captcha;
23 use JFB_Modules\Captcha\Hcaptcha\Hcaptcha;
24 use JFB_Modules\Captcha\Re_Captcha_V3\Re_Captcha_V3;
25 use JFB_Modules\Captcha\Turnstile\Turnstile;
26 use JFB_Components\Module\Base_Module_After_Install_It;
27 use JFB_Components\Module\Base_Module_Dir_It;
28 use JFB_Components\Module\Base_Module_Dir_Trait;
29 use JFB_Components\Module\Base_Module_Handle_It;
30 use JFB_Components\Module\Base_Module_Handle_Trait;
31 use JFB_Components\Module\Base_Module_It;
32 use JFB_Components\Module\Base_Module_Url_It;
33 use JFB_Components\Module\Base_Module_Url_Trait;
34 use JFB_Modules\Security\Exceptions\Spam_Exception;
35 use Jet_Form_Builder\Plugin;
36
37 /**
38 * @since 3.1.0
39 *
40 * Class Module
41 * @package JFB_Modules\Captcha
42 */
43 final class Module implements
44 Base_Module_It,
45 Base_Module_Url_It,
46 Base_Module_Dir_It,
47 Base_Module_After_Install_It,
48 Base_Module_Handle_It {
49
50 use Base_Module_Handle_Trait;
51 use Base_Module_Url_Trait;
52 use Base_Module_Dir_Trait;
53
54 use Repository_Pattern_Trait;
55
56 const PREFIX = 'jet_form_builder_captcha__';
57
58 /**
59 * @var Base_Captcha[]
60 */
61 private $current = array();
62
63 /**
64 * It becomes false inside `on_render_field`, if it renders the captcha.
65 * And if it true - captcha renders inside the `on_end_render_form` method
66 *
67 * @var bool
68 */
69 private $should_render = true;
70
71 public function rep_item_id() {
72 return 'captcha';
73 }
74
75 public function on_install() {
76 $this->rep_install();
77
78 Tab_Handler_Manager::instance()->install( new Admin_Tabs\Captcha_Handler() );
79 }
80
81 public function on_uninstall() {
82 $this->rep_clear();
83
84 Tab_Handler_Manager::instance()->uninstall( 'captcha-tab' );
85 }
86
87 public function rep_instances(): array {
88 return apply_filters(
89 'jet-form-builder/captcha/types',
90 array(
91 new Re_Captcha_V3(),
92 new Hcaptcha(),
93 new Turnstile(),
94 new Friendly_Captcha(),
95 )
96 );
97 }
98
99 public function condition(): bool {
100 return true;
101 }
102
103 public function init_hooks() {
104 add_filter( 'jet-form-builder/request-handler/request', array( $this, 'on_request' ) );
105 add_filter( 'jet-form-builder/before-render-field', array( $this, 'on_render_field' ), 10, 3 );
106 add_filter( 'jet-form-builder/page-config/jfb-settings', array( $this, 'on_localize_config' ) );
107 add_filter( 'jet-form-builder/editor/config', array( $this, 'on_localize_config' ) );
108 add_filter( 'jet-form-builder/setup-blocks', array( $this, 'check_is_container_exist' ) );
109 add_filter( 'jet-form-builder/before-end-form', array( $this, 'on_end_render_form' ) );
110 add_filter( 'jet-form-builder/blocks/items', array( $this, 'add_blocks_types' ) );
111
112 add_action( 'jet-form-builder/editor-assets/before', array( $this, 'enqueue_editor_assets' ) );
113 add_action( 'jet-form-builder/editor-assets/before', array( $this, 'enqueue_editor_package_assets' ), 0 );
114 add_action( 'wp_enqueue_scripts', array( $this, 'register_frontend_scripts' ) );
115 add_action( 'jet_plugins/frontend/register_scripts', array( $this, 'register_frontend_scripts' ) );
116 add_action( 'jet-form-builder/enqueue-style', array( $this, 'register_frontend_styles' ) );
117 }
118
119 public function remove_hooks() {
120 remove_filter( 'jet-form-builder/request-handler/request', array( $this, 'on_request' ) );
121 remove_filter( 'jet-form-builder/before-render-field', array( $this, 'on_render_field' ) );
122 remove_filter( 'jet-form-builder/page-config/jfb-settings', array( $this, 'on_localize_config' ) );
123 remove_filter( 'jet-form-builder/editor/config', array( $this, 'on_localize_config' ) );
124 remove_filter( 'jet-form-builder/setup-blocks', array( $this, 'check_is_container_exist' ) );
125 remove_filter( 'jet-form-builder/before-end-form', array( $this, 'on_end_render_form' ) );
126 remove_filter( 'jet-form-builder/blocks/items', array( $this, 'add_blocks_types' ) );
127
128 remove_action( 'jet-form-builder/editor-assets/before', array( $this, 'enqueue_editor_assets' ) );
129 remove_action(
130 'jet-form-builder/editor-assets/before',
131 array( $this, 'enqueue_editor_package_assets' ),
132 0
133 );
134 remove_action( 'wp_enqueue_scripts', array( $this, 'register_frontend_scripts' ) );
135 remove_action( 'jet_plugins/frontend/register_scripts', array( $this, 'register_frontend_scripts' ) );
136 remove_action( 'jet-form-builder/enqueue-style', array( $this, 'register_frontend_styles' ) );
137 }
138
139 /**
140 * @param $request
141 *
142 * @return mixed
143 * @throws Spam_Exception
144 */
145 public function on_request( $request ) {
146 $this->verify( $request );
147
148 return $request;
149 }
150
151 /**
152 * By default, the captcha is displayed before the submit button.
153 * But if the Captcha Container block is present in the form, we can check it in advance.
154 * This is necessary because the captcha and the button can be in parallel columns.
155 *
156 * @param string $content
157 * @param string $field_name
158 * @param array $attrs
159 *
160 * @return string
161 * @see Forms_Captcha::check_is_container_exist
162 */
163 public function on_render_field( string $content, string $field_name, array $attrs ): string {
164 $type = $attrs['action_type'] ?? '';
165
166 if ( 'submit-field' !== $field_name || 'submit' !== $type ) {
167 return $content;
168 }
169
170 try {
171 $current = $this->get_current();
172 } catch ( Repository_Exception $exception ) {
173 return $content;
174 }
175
176 $this->should_render = false;
177
178 if ( $current->is_exist_container() ) {
179 return $content;
180 }
181
182 return ( $content . $this->render() );
183 }
184
185 /**
186 * If for some reason the submit button has not been rendered in the form,
187 * then to make sure that we have displayed the captcha,
188 * we display it at the end of the rendering of the entire form.
189 *
190 * @param string $content
191 *
192 * @return string
193 */
194 public function on_end_render_form( string $content ): string {
195 $should_render = $this->should_render;
196 $this->should_render = true;
197
198 if ( $should_render ) {
199 $content .= $this->render();
200 }
201
202 return $content;
203 }
204
205 public function add_blocks_types( array $block_types ): array {
206 $block_types[] = new Block_Types\Captcha_Container();
207
208 return $block_types;
209 }
210
211 public function register_frontend_scripts() {
212 /** @var Base_Captcha $captcha */
213 foreach ( $this->rep_generate_items() as $captcha ) {
214 if ( ! ( $captcha instanceof Captcha_Separate_Frontend_Script ) ) {
215 continue;
216 }
217 $captcha->register_frontend_scripts();
218 }
219 }
220
221 public function register_frontend_styles() {
222 try {
223 $current = $this->get_current();
224 } catch ( Repository_Exception $exception ) {
225 return;
226 }
227 if ( ! ( $current instanceof Captcha_Frontend_Style_It ) ) {
228 return;
229 }
230 $current->register_frontend_styles();
231 }
232
233 public function enqueue_editor_assets() {
234 $script_asset = require_once $this->get_dir( 'assets/build/editor.asset.php' );
235
236 wp_enqueue_script(
237 $this->get_handle(),
238 $this->get_url( 'assets/build/editor.js' ),
239 $script_asset['dependencies'],
240 $script_asset['version'],
241 true
242 );
243
244 /** @var Base_Captcha $captcha */
245 foreach ( $this->rep_generate_items() as $captcha ) {
246 if ( ! ( $captcha instanceof Captcha_Separate_Editor_Script ) ) {
247 continue;
248 }
249 $captcha->enqueue_editor_script();
250 }
251 }
252
253 public function enqueue_editor_package_assets() {
254 $script_asset = require_once $this->get_dir( 'assets/build/editor.package.asset.php' );
255
256 wp_enqueue_script(
257 $this->get_handle( 'package' ),
258 $this->get_url( 'assets/build/editor.package.js' ),
259 $script_asset['dependencies'],
260 $script_asset['version'],
261 true
262 );
263 }
264
265 /**
266 * @param $request
267 *
268 * @throws Spam_Exception
269 */
270 protected function verify( $request ) {
271 try {
272 $this->get_current()->verify( $request );
273 } catch ( Repository_Exception $exception ) {
274 return;
275 }
276 }
277
278 public function render(): string {
279 try {
280 return $this->get_current()->get_output();
281 } catch ( Repository_Exception $exception ) {
282 return '';
283 } catch ( Render_Empty_Field $exception ) {
284 return '';
285 }
286 }
287
288 /**
289 * Returns captcha settings for current form
290 *
291 * @return Base_Captcha
292 * @throws Repository_Exception
293 */
294 public function get_current(): Base_Captcha {
295 if ( ! jet_fb_live()->form_id ) {
296 throw new Repository_Exception( 'no_captcha' );
297 }
298
299 if ( array_key_exists( (int) jet_fb_live()->form_id, $this->current ) ) {
300 if ( $this->current[ jet_fb_live()->form_id ] instanceof Base_Captcha ) {
301 return $this->current[ jet_fb_live()->form_id ];
302 }
303
304 throw new Repository_Exception( 'no_captcha' );
305 }
306
307 $settings = Plugin::instance()->post_type->get_captcha( jet_fb_live()->form_id );
308
309 if ( ! $settings || ! is_array( $settings ) ) {
310 $this->current[ jet_fb_live()->form_id ] = false;
311
312 throw new Repository_Exception( 'no_captcha' );
313 }
314
315 $captcha = $settings['captcha'] ?? false;
316
317 /**
318 * For backward compatibility
319 */
320 if ( false === $captcha && ! empty( $settings['enabled'] ) ) {
321 $captcha = Re_Captcha_V3::class;
322 }
323
324 /**
325 * @var Base_Captcha $current
326 */
327 $current = $this->rep_clone_item( $captcha );
328
329 $this->current[ jet_fb_live()->form_id ] = $current->sanitize_options( $settings );
330
331 return $this->current[ jet_fb_live()->form_id ];
332 }
333
334 public function on_localize_config( array $config ): array {
335 $captcha_config = array();
336
337 /** @var Base_Captcha $captcha */
338 foreach ( $this->rep_generate_items() as $captcha ) {
339 if ( ! ( $captcha instanceof Captcha_Settings_From_Options ) ) {
340 continue;
341 }
342 $captcha_config[] = $captcha->to_array();
343 }
344
345 $config['captcha-tab-config'] = $captcha_config;
346
347 return $config;
348 }
349
350 public function check_is_container_exist( array $blocks ): array {
351 try {
352 $current = $this->get_current();
353 } catch ( Repository_Exception $exception ) {
354 return $blocks;
355 }
356
357 if ( ! is_null( $current->is_exist_container() ) ) {
358 return $blocks;
359 }
360
361 $current->set_exist_container(
362 ! empty(
363 Block_Helper::find_by_block_name(
364 $blocks,
365 'jet-forms/captcha-container'
366 )
367 )
368 );
369
370 return $blocks;
371 }
372
373 /**
374 * @param string|array $config
375 * @param string $handle
376 *
377 * @return bool
378 */
379 public function add_inline_config( $config, string $handle = '' ): bool {
380 $form_id = jet_fb_live()->form_id;
381
382 if ( ! is_string( $config ) ) {
383 $config = Tools::encode_json( $config );
384 }
385
386 return wp_add_inline_script(
387 $handle ?: Base_Captcha::HANDLE_USER,
388 "
389 window.JetFormBuilderCaptchaConfig = window.JetFormBuilderCaptchaConfig || {};
390 window.JetFormBuilderCaptchaConfig[ $form_id ] = {$config};
391 ",
392 'before'
393 );
394 }
395 }
396