PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 3.5.1.2
JetFormBuilder — Dynamic Blocks Form Builder v3.5.1.2
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 / security / honeypot / module.php
jetformbuilder / modules / security / honeypot Last commit date
module.php 1 year ago
module.php
173 lines
1 <?php
2
3
4 namespace JFB_Modules\Security\Honeypot;
5
6 use Jet_Form_Builder\Exceptions\Request_Exception;
7 use Jet_Form_Builder\Live_Form;
8 use JFB_Components\Module\Base_Module_It;
9 use JFB_Modules\Security\Exceptions\Spam_Exception;
10
11 // If this file is called directly, abort.
12 if ( ! defined( 'WPINC' ) ) {
13 die;
14 }
15
16 class Module implements Base_Module_It {
17
18 const FIELD = '_jfb_email_hp_';
19
20 public function rep_item_id() {
21 return 'honeypot';
22 }
23
24 public function condition(): bool {
25 return true;
26 }
27
28 const SPAM_EXCEPTION = 'honeypot';
29 public function __construct() {
30 add_filter( 'jet-form-builder/security/spam-statuses', array( $this, 'add_spam_statuses' ) );
31 }
32 public function add_spam_statuses( $statuses ) {
33 $statuses[] = self::SPAM_EXCEPTION;
34 return $statuses;
35 }
36
37 public function init_hooks() {
38 add_filter(
39 'jet-form-builder/before-render-field',
40 array( $this, 'on_render_field' ),
41 10,
42 3
43 );
44 add_filter(
45 'jet-form-builder/request-handler/request',
46 array( $this, 'handle_request' )
47 );
48 add_filter(
49 'jet-form-builder/message-types',
50 array( $this, 'handle_global_messages' )
51 );
52 }
53
54 public function remove_hooks() {
55 remove_filter(
56 'jet-form-builder/before-render-field',
57 array( $this, 'on_render_field' )
58 );
59 remove_filter(
60 'jet-form-builder/request-handler/request',
61 array( $this, 'handle_request' )
62 );
63 remove_filter(
64 'jet-form-builder/message-types',
65 array( $this, 'handle_global_messages' )
66 );
67 }
68
69 private function find_email_field_name( array $blocks ): string {
70 $result = array(
71 'has_email' => false,
72 'has__email' => false,
73 );
74
75 $this->walk_blocks_for_email( $blocks, $result );
76
77 if ( $result['has_email'] ) {
78 if ( $result['has__email'] ) {
79 return self::FIELD;
80 }
81 return '_email';
82 }
83
84 return 'email';
85 }
86
87 private function walk_blocks_for_email( array $blocks, array &$result ) {
88 foreach ( $blocks as $block ) {
89 if ( ! is_array( $block ) ) {
90 continue;
91 }
92
93 if ( isset( $block['attrs']['name'] ) ) {
94 if ( 'email' === $block['attrs']['name'] ) {
95 $result['has_email'] = true;
96 }
97 if ( '_email' === $block['attrs']['name'] ) {
98 $result['has__email'] = true;
99 }
100 }
101
102 if ( ! empty( $block['innerBlocks'] ) && is_array( $block['innerBlocks'] ) ) {
103 $this->walk_blocks_for_email( $block['innerBlocks'], $result );
104 }
105 }
106 }
107
108 public function on_render_field( string $content, string $field_name, array $attrs ): string {
109 $type = $attrs['action_type'] ?? '';
110 if ( 'submit-field' !== $field_name || 'submit' !== $type ) {
111 return $content;
112 }
113
114 $args = jet_form_builder()->post_type->get_args();
115 if ( empty( $args['use_honeypot'] ) ) {
116 return $content;
117 }
118
119 $name = $this->find_email_field_name( Live_Form::instance()->blocks );
120
121 $field = Live_Form::force_render_field(
122 'text-field',
123 array(
124 'field_type' => 'email',
125 'name' => $name,
126 'autocomplete' => 'off',
127 )
128 );
129
130 $content .= sprintf(
131 '<div class="jfb-visually-hidden" tabindex="-1">%s</div>',
132 $field
133 );
134
135 return $content;
136 }
137
138 /**
139 * @param array $request
140 *
141 * @return array
142 * @throws Spam_Exception
143 */
144 public function handle_request( array $request ): array {
145 $args = jet_form_builder()->post_type->get_args();
146
147 if ( empty( $args['use_honeypot'] ) ) {
148 return $request;
149 }
150
151 $honeypot_name = $this->find_email_field_name( jet_form_builder()->form_handler->request_handler->_fields );
152
153 if ( ! empty( $request[ $honeypot_name ] ) ) {
154 // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped
155 throw new Spam_Exception( self::SPAM_EXCEPTION );
156 }
157
158 unset( $request[ $honeypot_name ] );
159
160 return $request;
161 }
162
163 public function handle_global_messages( array $types ): array {
164 $types[ self::SPAM_EXCEPTION ] = array(
165 'label' => __( 'Honeypot validation failed', 'jet-form-builder' ),
166 'value' => __( 'You are not allowed to fill in the honeypot field', 'jet-form-builder' ),
167 );
168
169 return $types;
170 }
171
172 }
173