PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.3-beta
16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 All 507 releases
jetpack / jetpack_vendor / automattic / jetpack-forms / src / service / class-hostinger-reach-integration.php

class-hostinger-reach-integration.php in Jetpack – WP Security, Backup, Speed, & Growth 16.3-beta, at jetpack_vendor/automattic/jetpack-forms/src/service/class-hostinger-reach-integration.php

243 lines 7.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Hostinger Reach Integration for Jetpack Contact Forms.
4 *
5 * @package automattic/jetpack
6 */
7
8 namespace Automattic\Jetpack\Forms\Service;
9
10 use Automattic\Jetpack\Forms\ContactForm\Feedback;
11
12 /**
13 * Class Hostinger_Reach_Integration
14 *
15 * Scaffolding for handling integration with Hostinger Reach for Jetpack Contact Forms.
16 * Public API docs are limited; this class mirrors the structure of MailPoet_Integration
17 * and will be implemented once the Hostinger Reach plugin APIs are confirmed.
18 */
19 class Hostinger_Reach_Integration {
20 /**
21 * Placeholder for a Hostinger Reach API instance, if needed later.
22 *
23 * @var mixed
24 */
25 protected static $hostinger_api = null;
26
27 /**
28 * Submit contact to Hostinger Reach.
29 *
30 * @param mixed $api_handler Reach API handler.
31 * @param array $subscriber_data Associative array: email, first_name, last_name.
32 * @param string $group_name Target group name.
33 * @return void
34 */
35 protected static function submit_contact( $api_handler, array $subscriber_data, $group_name ) {
36 if ( ! $api_handler || empty( $subscriber_data['email'] ) ) {
37 return;
38 }
39
40 $subscriber_data['group'] = $group_name;
41 $api_handler->post_contact( $subscriber_data );
42 }
43
44 /**
45 * Get the Hostinger Reach API instance.
46 *
47 * @return mixed
48 */
49 protected static function get_api() {
50 if (
51 null === self::$hostinger_api
52 // @phan-suppress-next-line PhanUndeclaredClassReference
53 && class_exists( \Hostinger\Reach\Api\Handlers\ReachApiHandler::class )
54 // @phan-suppress-next-line PhanUndeclaredClassReference
55 && class_exists( \Hostinger\Reach\Functions::class )
56 // @phan-suppress-next-line PhanUndeclaredClassReference
57 && class_exists( \Hostinger\Reach\Api\ApiKeyManager::class )
58 ) {
59 // @phan-suppress-next-line PhanUndeclaredClassMethod
60 self::$hostinger_api = new \Hostinger\Reach\Api\Handlers\ReachApiHandler(
61 // @phan-suppress-next-line PhanUndeclaredClassMethod
62 new \Hostinger\Reach\Functions(),
63 // @phan-suppress-next-line PhanUndeclaredClassMethod
64 new \Hostinger\Reach\Api\ApiKeyManager()
65 );
66 }
67
68 return self::$hostinger_api;
69 }
70
71 /**
72 * Get group name from form attributes, falling back to 'Jetpack Forms'.
73 *
74 * @param mixed $form Contact form instance.
75 * @return string
76 */
77 protected static function get_group_name( $form ) {
78 $group_name = ! empty( $form->attributes['hostingerReach']['groupName'] ?? '' )
79 ? trim( $form->attributes['hostingerReach']['groupName'] )
80 : 'Jetpack Forms';
81 return $group_name;
82 }
83
84 /**
85 * Extract subscriber data (email, first_name, last_name) using Feedback API (v2 storage).
86 *
87 * @param Feedback $feedback Feedback object for the submission.
88 * @return array Associative array with at least 'email', optionally 'first_name', 'last_name'. Empty array if no email found.
89 */
90 protected static function get_subscriber_data( $feedback ) {
91 if ( ! $feedback->get_author_email() ) {
92 return array();
93 }
94
95 $subscriber_data = array();
96 $subscriber_data['email'] = $feedback->get_author_email();
97
98 if ( $feedback->get_field_value_by_label( 'First Name' ) ) {
99 $subscriber_data['name'] = $feedback->get_field_value_by_label( 'First Name' );
100 } elseif ( $feedback->get_field_value_by_form_field_id( 'firstname' ) ) {
101 $subscriber_data['name'] = $feedback->get_field_value_by_form_field_id( 'firstname' );
102 } elseif ( $feedback->get_field_value_by_form_field_id( 'first-name' ) ) {
103 $subscriber_data['name'] = $feedback->get_field_value_by_form_field_id( 'first-name' );
104 }
105 if ( $feedback->get_field_value_by_label( 'Last Name' ) ) {
106 $subscriber_data['surname'] = $feedback->get_field_value_by_label( 'Last Name' );
107 } elseif ( $feedback->get_field_value_by_form_field_id( 'lastname' ) ) {
108 $subscriber_data['surname'] = $feedback->get_field_value_by_form_field_id( 'lastname' );
109 } elseif ( $feedback->get_field_value_by_form_field_id( 'last-name' ) ) {
110 $subscriber_data['surname'] = $feedback->get_field_value_by_form_field_id( 'last-name' );
111 }
112
113 return $subscriber_data;
114 }
115
116 /**
117 * Extract subscriber data (email, first_name, last_name) from legacy field data (v1 storage).
118 *
119 * @param array $fields Collection of Contact_Form_Field instances.
120 * @return array Associative array with at least 'email', optionally 'first_name', 'last_name'. Empty array if no email found.
121 */
122 protected static function get_subscriber_data_from_fields( $fields ) {
123 $subscriber_data = array();
124
125 foreach ( $fields as $field ) {
126 $id = strtolower( str_replace( array( ' ', '_' ), '', $field->get_attribute( 'id' ) ) );
127 $label = strtolower( str_replace( array( ' ', '_' ), '', $field->get_attribute( 'label' ) ) );
128
129 if ( ! is_string( $field->value ) ) {
130 continue;
131 }
132
133 $value = trim( $field->value );
134
135 if ( ( $id === 'email' || $label === 'email' ) && ! empty( $value ) ) {
136 $subscriber_data['email'] = $value;
137 } elseif ( ( $id === 'firstname' || $label === 'firstname' ) && ! empty( $value ) ) {
138 $subscriber_data['name'] = $value;
139 } elseif ( ( $id === 'lastname' || $label === 'lastname' ) && ! empty( $value ) ) {
140 $subscriber_data['surname'] = $value;
141 }
142 }
143
144 if ( empty( $subscriber_data['email'] ) ) {
145 return array();
146 }
147
148 return $subscriber_data;
149 }
150
151 /**
152 * Check if submission has consent when required.
153 *
154 * @param Feedback $feedback Feedback object for the submission.
155 * @param array $fields Visible submitted fields.
156 * @param bool $uses_feedback_api Whether the data uses structured feedback storage.
157 * @return bool True if consent is present or not required; false otherwise.
158 */
159 protected static function has_consent( $feedback, $fields, $uses_feedback_api ) {
160 if ( $uses_feedback_api ) {
161 if ( $feedback->has_field_type( 'consent' ) && ! $feedback->has_consent() ) {
162 return false;
163 }
164 return true;
165 }
166
167 $consent_field = null;
168 if ( is_array( $fields ) ) {
169 foreach ( $fields as $form_field ) {
170 if ( 'consent' === $form_field->get_attribute( 'type' ) ) {
171 $consent_field = $form_field;
172 break;
173 }
174 }
175 }
176 if ( $consent_field ) {
177 $consent_type = strtolower( (string) $consent_field->get_attribute( 'consenttype' ) );
178 if ( 'explicit' === $consent_type && ! $consent_field->value ) {
179 return false;
180 }
181 }
182
183 return true;
184 }
185
186 /**
187 * Handle Hostinger Reach integration after feedback post is inserted.
188 *
189 * For now, this only validates preconditions and returns early; real actions will be implemented later.
190 *
191 * @param int $post_id The post ID for the feedback CPT.
192 * @param array $fields Collection of Contact_Form_Field instances.
193 * @param bool $is_spam Whether the submission is spam.
194 */
195 public static function handle_hostinger_reach_integration( $post_id, $fields, $is_spam ) {
196 if ( $is_spam ) {
197 return;
198 }
199
200 // Try and get the form from any of the fields
201 $form = null;
202 foreach ( $fields as $field ) {
203 if ( ! empty( $field->form ) ) {
204 $form = $field->form;
205 break;
206 }
207 }
208 if ( ! $form || ! is_a( $form, 'Automattic\\Jetpack\\Forms\\ContactForm\\Contact_Form' ) ) {
209 return;
210 }
211
212 // Feature is toggled per-form.
213 if ( empty( $form->attributes['hostingerReach']['enabledForForm'] ?? null ) ) {
214 return;
215 }
216
217 $feedback = Feedback::get( $post_id );
218 if ( ! $feedback ) {
219 return;
220 }
221
222 $api_handler = self::get_api();
223 if ( ! $api_handler ) {
224 return;
225 }
226
227 // Respect consent if a consent field exists.
228 $uses_feedback_api = $feedback->uses_structured_fields();
229 if ( ! self::has_consent( $feedback, $fields, $uses_feedback_api ) ) {
230 return;
231 }
232
233 $subscriber_data = $uses_feedback_api ? self::get_subscriber_data( $feedback ) : self::get_subscriber_data_from_fields( $fields );
234 if ( empty( $subscriber_data ) ) {
235 return;
236 }
237
238 $group_name = self::get_group_name( $form );
239
240 self::submit_contact( $api_handler, $subscriber_data, $group_name );
241 }
242 }
243