PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 3.4.6
JetFormBuilder — Dynamic Blocks Form Builder v3.4.6
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 1 year ago hcaptcha 1 year ago re-captcha-v3 1 year ago turnstile 1 year ago .eslintrc.js 1 year ago module.php 1 year ago
module.php
405 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 const SPAM_EXCEPTION = 'captcha_failed';
58
59 /**
60 * @var Base_Captcha[]
61 */
62 private $current = array();
63
64 /**
65 * It becomes false inside `on_render_field`, if it renders the captcha.
66 * And if it true - captcha renders inside the `on_end_render_form` method
67 *
68 * @var bool
69 */
70 private $should_render = true;
71
72 public function rep_item_id() {
73 return 'captcha';
74 }
75
76 public function __construct() {
77 add_action( 'jet-form-builder/security/spam-statuses', array( $this, 'add_spam_statuses' ) );
78 }
79 public function add_spam_statuses( $statuses ) {
80 $statuses[] = self::SPAM_EXCEPTION;
81 return $statuses;
82 }
83
84 public function on_install() {
85 $this->rep_install();
86
87 Tab_Handler_Manager::instance()->install( new Admin_Tabs\Captcha_Handler() );
88 }
89
90 public function on_uninstall() {
91 $this->rep_clear();
92
93 Tab_Handler_Manager::instance()->uninstall( 'captcha-tab' );
94 }
95
96 public function rep_instances(): array {
97 return apply_filters(
98 'jet-form-builder/captcha/types',
99 array(
100 new Re_Captcha_V3(),
101 new Hcaptcha(),
102 new Turnstile(),
103 new Friendly_Captcha(),
104 )
105 );
106 }
107
108 public function condition(): bool {
109 return true;
110 }
111
112 public function init_hooks() {
113 add_filter( 'jet-form-builder/request-handler/request', array( $this, 'on_request' ) );
114 add_filter( 'jet-form-builder/before-render-field', array( $this, 'on_render_field' ), 10, 3 );
115 add_filter( 'jet-form-builder/page-config/jfb-settings', array( $this, 'on_localize_config' ) );
116 add_filter( 'jet-form-builder/editor/config', array( $this, 'on_localize_config' ) );
117 add_filter( 'jet-form-builder/setup-blocks', array( $this, 'check_is_container_exist' ) );
118 add_filter( 'jet-form-builder/before-end-form', array( $this, 'on_end_render_form' ) );
119 add_filter( 'jet-form-builder/blocks/items', array( $this, 'add_blocks_types' ) );
120
121 add_action( 'jet-form-builder/editor-assets/before', array( $this, 'enqueue_editor_assets' ) );
122 add_action( 'jet-form-builder/editor-assets/before', array( $this, 'enqueue_editor_package_assets' ), 0 );
123 add_action( 'wp_enqueue_scripts', array( $this, 'register_frontend_scripts' ) );
124 add_action( 'jet_plugins/frontend/register_scripts', array( $this, 'register_frontend_scripts' ) );
125 add_action( 'jet-form-builder/enqueue-style', array( $this, 'register_frontend_styles' ) );
126 }
127
128 public function remove_hooks() {
129 remove_filter( 'jet-form-builder/request-handler/request', array( $this, 'on_request' ) );
130 remove_filter( 'jet-form-builder/before-render-field', array( $this, 'on_render_field' ) );
131 remove_filter( 'jet-form-builder/page-config/jfb-settings', array( $this, 'on_localize_config' ) );
132 remove_filter( 'jet-form-builder/editor/config', array( $this, 'on_localize_config' ) );
133 remove_filter( 'jet-form-builder/setup-blocks', array( $this, 'check_is_container_exist' ) );
134 remove_filter( 'jet-form-builder/before-end-form', array( $this, 'on_end_render_form' ) );
135 remove_filter( 'jet-form-builder/blocks/items', array( $this, 'add_blocks_types' ) );
136
137 remove_action( 'jet-form-builder/editor-assets/before', array( $this, 'enqueue_editor_assets' ) );
138 remove_action(
139 'jet-form-builder/editor-assets/before',
140 array( $this, 'enqueue_editor_package_assets' ),
141 0
142 );
143 remove_action( 'wp_enqueue_scripts', array( $this, 'register_frontend_scripts' ) );
144 remove_action( 'jet_plugins/frontend/register_scripts', array( $this, 'register_frontend_scripts' ) );
145 remove_action( 'jet-form-builder/enqueue-style', array( $this, 'register_frontend_styles' ) );
146 }
147
148 /**
149 * @param $request
150 *
151 * @return mixed
152 * @throws Spam_Exception
153 */
154 public function on_request( $request ) {
155 $this->verify( $request );
156
157 return $request;
158 }
159
160 /**
161 * By default, the captcha is displayed before the submit button.
162 * But if the Captcha Container block is present in the form, we can check it in advance.
163 * This is necessary because the captcha and the button can be in parallel columns.
164 *
165 * @param string $content
166 * @param string $field_name
167 * @param array $attrs
168 *
169 * @return string
170 * @see Forms_Captcha::check_is_container_exist
171 */
172 public function on_render_field( string $content, string $field_name, array $attrs ): string {
173 $type = $attrs['action_type'] ?? '';
174
175 if ( 'submit-field' !== $field_name || 'submit' !== $type ) {
176 return $content;
177 }
178
179 try {
180 $current = $this->get_current();
181 } catch ( Repository_Exception $exception ) {
182 return $content;
183 }
184
185 $this->should_render = false;
186
187 if ( $current->is_exist_container() ) {
188 return $content;
189 }
190
191 return ( $content . $this->render() );
192 }
193
194 /**
195 * If for some reason the submit button has not been rendered in the form,
196 * then to make sure that we have displayed the captcha,
197 * we display it at the end of the rendering of the entire form.
198 *
199 * @param string $content
200 *
201 * @return string
202 */
203 public function on_end_render_form( string $content ): string {
204 $should_render = $this->should_render;
205 $this->should_render = true;
206
207 if ( $should_render ) {
208 $content .= $this->render();
209 }
210
211 return $content;
212 }
213
214 public function add_blocks_types( array $block_types ): array {
215 $block_types[] = new Block_Types\Captcha_Container();
216
217 return $block_types;
218 }
219
220 public function register_frontend_scripts() {
221 /** @var Base_Captcha $captcha */
222 foreach ( $this->rep_generate_items() as $captcha ) {
223 if ( ! ( $captcha instanceof Captcha_Separate_Frontend_Script ) ) {
224 continue;
225 }
226 $captcha->register_frontend_scripts();
227 }
228 }
229
230 public function register_frontend_styles() {
231 try {
232 $current = $this->get_current();
233 } catch ( Repository_Exception $exception ) {
234 return;
235 }
236 if ( ! ( $current instanceof Captcha_Frontend_Style_It ) ) {
237 return;
238 }
239 $current->register_frontend_styles();
240 }
241
242 public function enqueue_editor_assets() {
243 $script_asset = require_once $this->get_dir( 'assets/build/editor.asset.php' );
244
245 wp_enqueue_script(
246 $this->get_handle(),
247 $this->get_url( 'assets/build/editor.js' ),
248 $script_asset['dependencies'],
249 $script_asset['version'],
250 true
251 );
252
253 /** @var Base_Captcha $captcha */
254 foreach ( $this->rep_generate_items() as $captcha ) {
255 if ( ! ( $captcha instanceof Captcha_Separate_Editor_Script ) ) {
256 continue;
257 }
258 $captcha->enqueue_editor_script();
259 }
260 }
261
262 public function enqueue_editor_package_assets() {
263 $script_asset = require_once $this->get_dir( 'assets/build/editor.package.asset.php' );
264
265 wp_enqueue_script(
266 $this->get_handle( 'package' ),
267 $this->get_url( 'assets/build/editor.package.js' ),
268 $script_asset['dependencies'],
269 $script_asset['version'],
270 true
271 );
272 }
273
274 /**
275 * @param $request
276 *
277 * @throws Spam_Exception
278 */
279 protected function verify( $request ) {
280 try {
281 $this->get_current()->verify( $request );
282 } catch ( Repository_Exception $exception ) {
283 return;
284 }
285 }
286
287 public function render(): string {
288 try {
289 return $this->get_current()->get_output();
290 } catch ( Repository_Exception $exception ) {
291 return '';
292 } catch ( Render_Empty_Field $exception ) {
293 return '';
294 }
295 }
296
297 /**
298 * Returns captcha settings for current form
299 *
300 * @return Base_Captcha
301 * @throws Repository_Exception
302 */
303 public function get_current(): Base_Captcha {
304 if ( ! jet_fb_live()->form_id ) {
305 throw new Repository_Exception( 'no_captcha' );
306 }
307
308 if ( array_key_exists( (int) jet_fb_live()->form_id, $this->current ) ) {
309 if ( $this->current[ jet_fb_live()->form_id ] instanceof Base_Captcha ) {
310 return $this->current[ jet_fb_live()->form_id ];
311 }
312
313 throw new Repository_Exception( 'no_captcha' );
314 }
315
316 $settings = Plugin::instance()->post_type->get_captcha( jet_fb_live()->form_id );
317
318 if ( ! $settings || ! is_array( $settings ) ) {
319 $this->current[ jet_fb_live()->form_id ] = false;
320
321 throw new Repository_Exception( 'no_captcha' );
322 }
323
324 $captcha = $settings['captcha'] ?? false;
325
326 /**
327 * For backward compatibility
328 */
329 if ( false === $captcha && ! empty( $settings['enabled'] ) ) {
330 $captcha = Re_Captcha_V3::class;
331 }
332
333 /**
334 * @var Base_Captcha $current
335 */
336 $current = $this->rep_clone_item( $captcha );
337
338 $this->current[ jet_fb_live()->form_id ] = $current->sanitize_options( $settings );
339
340 return $this->current[ jet_fb_live()->form_id ];
341 }
342
343 public function on_localize_config( array $config ): array {
344 $captcha_config = array();
345
346 /** @var Base_Captcha $captcha */
347 foreach ( $this->rep_generate_items() as $captcha ) {
348 if ( ! ( $captcha instanceof Captcha_Settings_From_Options ) ) {
349 continue;
350 }
351 $captcha_config[] = $captcha->to_array();
352 }
353
354 $config['captcha-tab-config'] = $captcha_config;
355
356 return $config;
357 }
358
359 public function check_is_container_exist( array $blocks ): array {
360 try {
361 $current = $this->get_current();
362 } catch ( Repository_Exception $exception ) {
363 return $blocks;
364 }
365
366 if ( ! is_null( $current->is_exist_container() ) ) {
367 return $blocks;
368 }
369
370 $current->set_exist_container(
371 ! empty(
372 Block_Helper::find_by_block_name(
373 $blocks,
374 'jet-forms/captcha-container'
375 )
376 )
377 );
378
379 return $blocks;
380 }
381
382 /**
383 * @param string|array $config
384 * @param string $handle
385 *
386 * @return bool
387 */
388 public function add_inline_config( $config, string $handle = '' ): bool {
389 $form_id = jet_fb_live()->form_id;
390
391 if ( ! is_string( $config ) ) {
392 $config = Tools::encode_json( $config );
393 }
394
395 return wp_add_inline_script(
396 $handle ?: Base_Captcha::HANDLE_USER,
397 "
398 window.JetFormBuilderCaptchaConfig = window.JetFormBuilderCaptchaConfig || {};
399 window.JetFormBuilderCaptchaConfig[ $form_id ] = {$config};
400 ",
401 'before'
402 );
403 }
404 }
405