PluginProbe ʕ •ᴥ•ʔ
Hustle – Email Marketing, Lead Generation, Optins, Popups / 7.8.14.1
Hustle – Email Marketing, Lead Generation, Optins, Popups v7.8.14.1
7.8.14 7.8.14.1 7.8.13 7.8.13.1 trunk 3.0 3.1 3.1.1 3.1.2 3.1.3 3.1.4 4.3.2 4.4.4 4.4.5 4.4.5.1 4.4.5.4 4.6 4.6.1.1 4.6.1.4 4.7.0.2 4.7.0.3 4.7.0.7 4.7.0.9 4.7.1.0 4.7.1.1 4.8.0.0 5.0.0 5.0.1 5.0.1.1 5.0.1.2 5.1 5.1.1 5.1.2 5.1.3 5.1.3.1 5.1.3.2 5.1.4 5.1.5 6.0 6.0.1 6.0.2 6.0.3 6.0.4.2 6.0.5 6.0.6.1 6.0.7 6.0.8.1 6.0.9 7.0.0.1 7.0.2 7.0.3 7.0.4 7.1.0 7.1.1 7.2.0 7.2.1 7.3.0 7.3.1 7.3.3 7.3.5 7.3.6 7.3.7 7.4.0 7.4.1 7.4.11 7.4.13 7.4.13.1 7.4.2 7.4.3 7.4.4 7.4.5 7.4.5.1 7.4.5.2 7.4.6 7.4.7 7.5.0 7.6.0 7.6.1 7.6.3 7.6.4 7.6.6 7.7.0 7.7.1 7.8.0 7.8.1 7.8.10 7.8.10.1 7.8.10.2 7.8.11 7.8.12 7.8.12.1 7.8.2 7.8.3 7.8.4 7.8.5 7.8.6 7.8.7 7.8.8 7.8.9 7.8.9.1 7.8.9.2 7.8.9.3
wordpress-popup / inc / providers / convertkit / hustle-convertkit.php
wordpress-popup / inc / providers / convertkit Last commit date
images 3 months ago convertkit.php 3 months ago hustle-convertkit-api-intefrace.php 3 months ago hustle-convertkit-api-v2.php 3 months ago hustle-convertkit-api.php 3 months ago hustle-convertkit-form-hooks.php 3 months ago hustle-convertkit-form-settings.php 5 months ago hustle-convertkit-v2.php 3 months ago hustle-convertkit.php 3 months ago
hustle-convertkit.php
473 lines
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 /**
3 * Hustle_ConvertKit class
4 *
5 * @package Hustle
6 */
7
8 if ( ! class_exists( 'Hustle_ConvertKit' ) ) :
9
10 include_once 'hustle-convertkit-api.php';
11
12 /**
13 * Convertkit Email Integration
14 *
15 * @class Hustle_ConvertKit
16 * @version 2.0.3
17 **/
18 class Hustle_ConvertKit extends Hustle_Provider_Abstract {
19
20 const SLUG = 'convertkit';
21
22 /**
23 * Api
24 *
25 * @var ConvertKit_Api_Interface
26 */
27 protected static $api;
28 /**
29 * Errors
30 *
31 * @var array
32 */
33 protected static $errors;
34
35 /**
36 * Provider Instance
37 *
38 * @since 3.0.5
39 *
40 * @var self|null
41 */
42 protected static $instance = null;
43
44 /**
45 * Slug
46 *
47 * @since 3.0.5
48 * @var string
49 */
50 protected $slug = 'convertkit';
51
52 /**
53 * Version
54 *
55 * @since 3.0.5
56 * @var string
57 */
58 protected $version = '1.0';
59
60 /**
61 * Class
62 *
63 * @since 3.0.5
64 * @var string
65 */
66 protected $class = __CLASS__;
67
68 /**
69 * Title
70 *
71 * @since 3.0.5
72 * @var string
73 */
74 protected $title = 'Kit';
75
76 /**
77 * Class name of form settings
78 *
79 * @var string
80 */
81 protected $form_settings = 'Hustle_ConvertKit_Form_Settings';
82
83 /**
84 * Class name of form hooks
85 *
86 * @since 4.0
87 * @var string
88 */
89 protected $form_hooks = 'Hustle_ConvertKit_Form_Hooks';
90
91 /**
92 * Array of options which should exist for confirming that settings are completed
93 *
94 * @since 4.0
95 * @var array
96 */
97 protected $completion_options = array( 'api_key', 'api_secret' );
98
99 /**
100 * Provider constructor.
101 */
102 public function __construct() {
103 $this->icon_2x = plugin_dir_url( __FILE__ ) . 'images/icon.png';
104 $this->logo_2x = plugin_dir_url( __FILE__ ) . 'images/logo.png';
105 }
106
107 /**
108 * Get Instance
109 *
110 * @return self|null
111 */
112 public static function get_instance() {
113 if ( is_null( self::$instance ) ) {
114 self::$instance = new static();
115 }
116
117 return self::$instance;
118 }
119
120 /**
121 * Get the wizard callbacks for the global settings.
122 *
123 * @since 4.0
124 *
125 * @return array
126 */
127 public function settings_wizards() {
128 return array(
129 array(
130 'callback' => array( $this, 'configure_api_key' ),
131 'is_completed' => array( $this, 'is_connected' ),
132 ),
133 );
134 }
135
136
137 /**
138 * Configure the API key settings. Global settings.
139 *
140 * @since 4.0
141 *
142 * @param array $submitted_data Submitted data.
143 * @return array
144 */
145 public function configure_api_key( $submitted_data ) {
146 $has_errors = false;
147 $default_data = array(
148 'api_key' => '',
149 'api_secret' => '',
150 'name' => '',
151 );
152 $current_data = $this->get_current_data( $default_data, $submitted_data );
153 $is_submit = isset( $submitted_data['api_key'] ) && isset( $submitted_data['api_secret'] );
154 $global_multi_id = $this->get_global_multi_id( $submitted_data );
155
156 $api_key_valid = true;
157 $api_secret_valid = true;
158
159 if ( $is_submit ) {
160
161 $api_key_valid = ! empty( $current_data['api_key'] );
162 $api_secret_valid = ! empty( $current_data['api_secret'] );
163 $api_key_validated = $api_key_valid
164 && $api_secret_valid
165 && $this->validate_credentials( $submitted_data['api_secret'], $submitted_data['api_key'] );
166
167 if ( ! $api_key_validated ) {
168 $error_message = $this->provider_connection_falied();
169 $api_key_valid = false;
170 $api_secret_valid = false;
171 $has_errors = true;
172 }
173
174 if ( ! $has_errors ) {
175 $settings_to_save = array(
176 'api_key' => $current_data['api_key'],
177 'api_secret' => $current_data['api_secret'],
178 'name' => $current_data['name'],
179 );
180 // If not active, activate it.
181 // TODO: Wrap this in a friendlier method.
182 if ( Hustle_Provider_Utils::is_provider_active( $this->slug )
183 || Hustle_Providers::get_instance()->activate_addon( $this->slug ) ) {
184 $this->save_multi_settings_values( $global_multi_id, $settings_to_save );
185 } else {
186 $error_message = __( "Provider couldn't be activated.", 'hustle' );
187 $has_errors = true;
188 }
189 }
190
191 if ( ! $has_errors ) {
192
193 return array(
194 'html' => Hustle_Provider_Utils::get_integration_modal_title_markup( __( 'ConvertKit Added', 'hustle' ), __( 'You can now go to your pop-ups, slide-ins and embeds and assign them to this integration', 'hustle' ) ),
195 'buttons' => array(
196 'close' => array(
197 'markup' => Hustle_Provider_Utils::get_provider_button_markup( __( 'Close', 'hustle' ), 'sui-button-ghost', 'close' ),
198 ),
199 ),
200 'redirect' => false,
201 'has_errors' => false,
202 'notification' => array(
203 'type' => 'success',
204 'text' => '<strong>' . $this->get_title() . '</strong> ' . esc_html__( 'Successfully connected', 'hustle' ),
205 ),
206 );
207
208 }
209 }
210
211 $options = array(
212 array(
213 'type' => 'wrapper',
214 'class' => $api_key_valid ? '' : 'sui-form-field-error',
215 'elements' => array(
216 'label' => array(
217 'type' => 'label',
218 'for' => 'api_key',
219 'value' => __( 'API Key', 'hustle' ),
220 ),
221 'api_key' => array(
222 'type' => 'text',
223 'name' => 'api_key',
224 'value' => $current_data['api_key'],
225 'placeholder' => __( 'Enter API Key', 'hustle' ),
226 'id' => 'api_key',
227 'icon' => 'key',
228 ),
229 'error' => array(
230 'type' => 'error',
231 'class' => $api_key_valid ? 'sui-hidden' : '',
232 'value' => __( 'Please enter a valid ConvertKit API key', 'hustle' ),
233 ),
234 ),
235 ),
236 array(
237 'type' => 'wrapper',
238 'class' => $api_secret_valid ? '' : 'sui-form-field-error',
239 'elements' => array(
240 'label' => array(
241 'type' => 'label',
242 'for' => 'api_secret',
243 'value' => __( 'API Secret', 'hustle' ),
244 ),
245 'api_secret' => array(
246 'type' => 'text',
247 'name' => 'api_secret',
248 'value' => $current_data['api_secret'],
249 'placeholder' => __( 'Enter API Secret', 'hustle' ),
250 'id' => 'api_secret',
251 'icon' => 'key',
252 ),
253 'error' => array(
254 'type' => 'error',
255 'class' => $api_secret_valid ? 'sui-hidden' : '',
256 'value' => __( 'Please enter a valid ConvertKit API secret', 'hustle' ),
257 ),
258 ),
259 ),
260 array(
261 'type' => 'wrapper',
262 'style' => 'margin-bottom: 0;',
263 'elements' => array(
264 'label' => array(
265 'type' => 'label',
266 'for' => 'instance-name-input',
267 'value' => __( 'Identifier', 'hustle' ),
268 ),
269 'name' => array(
270 'type' => 'text',
271 'name' => 'name',
272 'value' => $current_data['name'],
273 'placeholder' => __( 'E.g. Business Account', 'hustle' ),
274 'id' => 'instance-name-input',
275 ),
276 'message' => array(
277 'type' => 'description',
278 'value' => __( 'Helps to distinguish your integrations if you have connected to the multiple accounts of this integration.', 'hustle' ),
279 ),
280 ),
281 ),
282 );
283
284 if ( $has_errors ) {
285 $error_notice = array(
286 'type' => 'notice',
287 'icon' => 'info',
288 'class' => 'sui-notice-error',
289 'value' => esc_html( $error_message ),
290 );
291 array_unshift( $options, $error_notice );
292 }
293
294 $step_html = Hustle_Provider_Utils::get_integration_modal_title_markup(
295 __( 'Configure ConvertKit', 'hustle' ),
296 sprintf(
297 /* translators: 1. opening 'a' tag to ConvertKit account, 2. closing 'a' tag */
298 __( 'Log in to your %1$sConvertKit%2$s account to get your API Key.', 'hustle' ),
299 '<a href="https://app.convertkit.com/account/edit" target="_blank">',
300 '</a>'
301 )
302 );
303 $step_html .= Hustle_Provider_Utils::get_html_for_options( $options );
304
305 $is_edit = $this->settings_are_completed( $global_multi_id );
306 if ( $is_edit ) {
307 $buttons = array(
308 'disconnect' => array(
309 'markup' => Hustle_Provider_Utils::get_provider_button_markup(
310 __( 'Disconnect', 'hustle' ),
311 'sui-button-ghost',
312 'disconnect',
313 true
314 ),
315 ),
316 'save' => array(
317 'markup' => Hustle_Provider_Utils::get_provider_button_markup(
318 __( 'Save', 'hustle' ),
319 '',
320 'connect',
321 true
322 ),
323 ),
324 );
325 } else {
326 $buttons = array(
327 'connect' => array(
328 'markup' => Hustle_Provider_Utils::get_provider_button_markup(
329 __( 'Connect', 'hustle' ),
330 'sui-button-right',
331 'connect',
332 true
333 ),
334 ),
335 );
336
337 }
338
339 $response = array(
340 'html' => $step_html,
341 'buttons' => $buttons,
342 'has_errors' => $has_errors,
343 );
344
345 return $response;
346 }
347
348 /**
349 * Validate the provided API key and API secret.
350 *
351 * @since 4.0
352 *
353 * @param string $api_secret Api secret.
354 * @param string $api_key Api key.
355 * @return bool
356 */
357 private function validate_credentials( $api_secret, $api_key ) {
358 if ( empty( $api_key ) ) {
359 return false;
360 }
361
362 try {
363 // Check if API key and API secret are valid.
364 $api = self::api( $api_key, $api_secret );
365 $subscribers = $api->get_subscribers(); // check API secret.
366 $forms = $api->get_forms(); // check API key.
367
368 if ( is_wp_error( $subscribers ) || is_wp_error( $forms ) ) {
369 Hustle_Provider_Utils::maybe_log( __METHOD__, __( 'Invalid ConvertKit API key ore API secret.', 'hustle' ) );
370 return false;
371 }
372 } catch ( Exception $e ) {
373 Hustle_Provider_Utils::maybe_log( __METHOD__, $e->getMessage() );
374 return false;
375 }
376
377 return true;
378 }
379
380
381 /**
382 * Get api
383 *
384 * @param string $api_key Api key.
385 * @param string $api_secret Api secret.
386 * @return Hustle_ConvertKit_Api_Interface
387 */
388 public static function api( $api_key, $api_secret = '' ) {
389
390 if ( empty( self::$api ) ) {
391 try {
392 self::$api = new Hustle_ConvertKit_Api( $api_key, $api_secret );
393 self::$errors = array();
394 } catch ( Exception $e ) {
395 self::$errors = array( 'api_error' => $e );
396 }
397 }
398 return self::$api;
399 }
400
401 /**
402 * Check if migration is needed.
403 * Migration is required if the provider is using version 1.0 (API key/secret authentication)
404 * and needs to migrate to version 2.0 (OAuth authentication).
405 *
406 * @since 4.6.0
407 * @return boolean
408 */
409 public function migration_required() {
410 $api_version = $this->get_installed_version();
411 if ( empty( $api_version ) ) {
412 return false;
413 }
414
415 $settings = $this->get_settings_values();
416
417 return ! empty( $settings ) &&
418 version_compare( $api_version, '2.0', '<' );
419 }
420
421 /**
422 * Get 3.0 provider mappings
423 *
424 * @return array
425 */
426 public function get_30_provider_mappings() {
427 return array(
428 'api_key' => 'api_key',
429 'api_secret' => 'api_secret',
430 );
431 }
432
433 /**
434 * Creates necessary custom fields for the form
435 *
436 * @param string $global_multi_id Global multi ID.
437 * @param array $fields Fields.
438 * @return array|mixed|object|WP_Error
439 */
440 public function maybe_create_custom_fields( $global_multi_id, array $fields ) {
441 $api_key = $this->get_setting( 'api_key', '', $global_multi_id );
442 $api_secret = $this->get_setting( 'api_secret', '', $global_multi_id );
443
444 // check if already existing.
445 $custom_fields = self::api( $api_key, $api_secret )->get_form_custom_fields();
446 $proceed = true;
447 foreach ( $custom_fields as $custom_field ) {
448 if ( isset( $fields[ $custom_field->key ] ) ) {
449 unset( $fields[ $custom_field->key ] );
450 }
451 }
452 // create necessary fields
453 // Note: we don't delete fields here, let the user do it on ConvertKit app.convertkit.com .
454 $api = self::api( $api_key );
455 foreach ( $fields as $key => $field ) {
456 $add_custom_field = $api->create_custom_fields(
457 array(
458 'api_secret' => $api_secret,
459 'label' => $field['label'],
460 )
461 );
462 if ( is_wp_error( $add_custom_field ) ) {
463 $proceed = false;
464 break;
465 }
466 }
467
468 return $proceed;
469 }
470 }
471
472 endif;
473