$settings ? 'sendtim-forms-settings' : 'sendtim-forms', 'notice' => $notice, 'edit' => $id ?: false ), admin_url( 'admin.php' ) ) ); exit; } private static function start( $title, $description ) { $notice = Sendtim_Forms::input( $_GET, 'notice' ); $messages = array( 'saved' => 'Saved. Your form is ready to place on your website.', 'deleted' => 'Form deleted.', 'connected' => 'Settings saved. Connection verified.', 'settings_saved' => 'Settings saved.', 'error' => 'Could not save. Check your connection, required fields and list selection.', 'connection_error' => 'Connection failed. Check your API key and network access.', 'crypto_error' => 'The API key could not be encrypted. OpenSSL is required.' ); echo '
Sendtim' . esc_html__( 'API guide ↗', 'sendtim-signup-forms' ) . '
'; echo '
' . esc_html__( 'AUDIENCE GROWTH', 'sendtim-signup-forms' ) . '

' . esc_html( $title ) . '

' . esc_html( $description ) . '

'; if ( isset( $messages[ $notice ] ) ) { echo '

' . esc_html( $messages[ $notice ] ) . '

'; } if ( '' === Sendtim_Signup_Settings::api_key() ) { echo '
' . esc_html__( 'Start by connecting your account in Sendtim → Settings.', 'sendtim-signup-forms' ) . '
'; } } public static function save_settings() { self::guard( 'sendtim_forms_settings' ); $result = Sendtim_Signup_Settings::set_api_key( Sendtim_Forms::input( $_POST, 'api_key' ), ! empty( $_POST['remove_key'] ) ); if ( is_wp_error( $result ) ) { self::redirect( 'crypto_error', 0, true ); } update_option( Sendtim_Forms::OPTIONS, array( 'popups' => ! empty( $_POST['popups'] ), 'double_opt_in' => ! empty( $_POST['double_opt_in'] ) ), false ); if ( '' === Sendtim_Signup_Settings::api_key() ) { self::redirect( 'settings_saved', 0, true ); } $test = ( new Sendtim_Signup_Api() )->me(); self::redirect( is_wp_error( $test ) ? 'connection_error' : 'connected', 0, true ); } public static function settings() { if ( ! current_user_can( 'manage_options' ) ) { return; } $s = Sendtim_Forms::settings(); self::start( __( 'A home for your growing audience.', 'sendtim-signup-forms' ), __( 'Connect once. Choose how your website welcomes new subscribers.', 'sendtim-signup-forms' ) ); ?>
01

02

'; return; } $posts = Sendtim_Forms::posts(); $form_count_label = sprintf( // translators: %d: Number of signup forms. __( 'Your signup forms (%d)', 'sendtim-signup-forms' ), count( $posts ) ); ?>

ID, Sendtim_Forms::META, true ); ?>

post_title ); ?>

[sendtim_form id="ID ); ?>"]
ID ); ?>

post_type ) ) { echo '

Form not found.

'; return; } $form = $id ? get_post_meta( $id, Sendtim_Forms::META, true ) : array(); $form = is_array( $form ) ? $form : array(); $d = $form['definition'] ?? array(); $remote = Sendtim_Forms::remote(); $lists_result = Sendtim_Signup_Settings::api_key() ? ( new Sendtim_Signup_Api() )->lists() : array(); $lists = ! is_wp_error( $lists_result ) ? ( $lists_result['data'] ?? array() ) : array(); if ( is_wp_error( $remote ) ) { echo '
' . esc_html__( 'Account forms could not be loaded. Verify your API key or try again later. You can still create a custom form when your lists are available.', 'sendtim-signup-forms' ) . '
'; } $type = ! empty( $form['remote_id'] ) ? 'remote' : 'custom'; ?>

$row ) { self::field_row( $index, $row ); } ?>

Back to forms
%2$s', esc_attr( $name ), esc_html( $label ), esc_attr( $value ), 'button' === $name ? 60 : 500 ); } private static function field_row( $index, $row ) { $prefix = 'extra[' . $index . ']'; echo '
'; } public static function save() { self::guard( 'sendtim_forms_save' ); $id = absint( Sendtim_Forms::input( $_POST, 'id' ) ); $post = $id ? get_post( $id ) : null; if ( $id && ( ! $post || Sendtim_Forms::TYPE !== $post->post_type ) ) { self::redirect( 'error' ); } $title = Sendtim_Forms::input( $_POST, 'title' ); if ( '' === $title || strlen( $title ) > 150 ) { self::redirect( 'error', $id ); } if ( 'remote' === Sendtim_Forms::input( $_POST, 'type' ) ) { $remote_id = Sendtim_Forms::input( $_POST, 'remote_id' ); $remote = Sendtim_Forms::remote_form( $remote_id, true ); if ( is_wp_error( $remote ) || 'inline' !== ( $remote['definition']['settings']['display']['mode'] ?? '' ) ) { self::redirect( 'error', $id ); } $form = array( 'remote_id' => $remote_id, 'account_hash' => hash( 'sha256', Sendtim_Signup_Settings::api_key() ) ); } else { $form = self::custom( $_POST ); if ( is_wp_error( $form ) ) { self::redirect( 'error', $id ); } } $saved = wp_insert_post( wp_slash( array( 'ID' => $id, 'post_type' => Sendtim_Forms::TYPE, 'post_status' => 'publish', 'post_title' => $title ) ), true ); if ( is_wp_error( $saved ) ) { self::redirect( 'error', $id ); } $form['account_hash'] = hash( 'sha256', Sendtim_Signup_Settings::api_key() ); update_post_meta( $saved, Sendtim_Forms::META, wp_slash( $form ) ); self::redirect( 'saved', $saved ); } private static function custom( $input ) { $api_lists = ( new Sendtim_Signup_Api() )->lists(); if ( is_wp_error( $api_lists ) ) { return $api_lists; } $lists = $api_lists['data'] ?? array(); $list_id = Sendtim_Forms::input( $input, 'list_id' ); if ( ! in_array( $list_id, array_column( $lists, 'id' ), true ) ) { return new WP_Error( 'list', 'Choose a list.' ); } $fields = array( array( 'type' => 'email', 'id' => 'email01', 'label' => 'Email address', 'required' => true ) ); $editor = array(); $extra = isset( $input['extra'] ) && is_array( $input['extra'] ) ? array_slice( $input['extra'], 0, 20 ) : array(); $mapped = array(); foreach ( $extra as $row ) { if ( ! is_array( $row ) ) { continue; } $label = Sendtim_Forms::input( $row, 'label' ); if ( '' === $label ) { continue; } $type = Sendtim_Forms::input( $row, 'type' ); $map = Sendtim_Forms::input( $row, 'mapping' ); $key = 'custom' === $map ? Sendtim_Forms::input( $row, 'key' ) : $map; if ( ! in_array( $type, array( 'text', 'textarea', 'number', 'select', 'phone', 'checkbox' ), true ) || ! in_array( $map, array( 'first_name', 'last_name', 'company', 'job_title', 'phone', 'country', 'city', 'custom' ), true ) || ! preg_match( '/^[a-z][a-z0-9_]{0,63}$/', $key ) || strlen( $label ) > 120 || isset( $mapped[ $map . ':' . $key ] ) ) { return new WP_Error( 'field', 'Invalid field.' ); } $mapped[ $map . ':' . $key ] = true; $field = array( 'type' => $type, 'id' => sprintf( 'field%02d', count( $fields ) ), 'label' => $label, 'required' => ! empty( $row['required'] ), 'mapping' => array( 'kind' => 'custom' === $map ? 'custom_property' : 'contact_field', 'key' => $key ) ); $options = isset( $row['options'] ) && is_string( $row['options'] ) ? sanitize_textarea_field( wp_unslash( $row['options'] ) ) : ''; if ( 'select' === $type ) { $choices = array_values( array_unique( array_filter( array_map( 'trim', explode( "\n", $options ) ) ) ) ); if ( ! $choices || count( $choices ) > 50 ) { return new WP_Error( 'choices', 'Invalid choices.' ); } $field['options'] = array(); foreach ( $choices as $choice ) { if ( strlen( $choice ) > 100 ) { return new WP_Error( 'choices', 'Choice too long.' ); } $field['options'][] = array( 'value' => $choice, 'label' => $choice ); } } $fields[] = $field; $editor[] = array( 'label' => $label, 'type' => $type, 'mapping' => $map, 'key' => 'custom' === $map ? $key : '', 'options' => $options, 'required' => ! empty( $row['required'] ) ); } $consent = Sendtim_Forms::input( $input, 'consent' ); $button = Sendtim_Forms::input( $input, 'button' ); $success = Sendtim_Forms::input( $input, 'success' ); if ( '' === $consent || strlen( $consent ) > 500 || '' === $button || strlen( $button ) > 60 || '' === $success || strlen( $success ) > 500 ) { return new WP_Error( 'copy', 'Invalid form text.' ); } $fields[] = array( 'type' => 'consent', 'id' => 'consent01', 'label' => $consent, 'required' => true ); $interests = array(); $chosen = isset( $input['interests'] ) && is_array( $input['interests'] ) ? $input['interests'] : array(); foreach ( $lists as $list ) { if ( $list['id'] !== $list_id && in_array( $list['id'], $chosen, true ) ) { $interests[] = array( 'id' => $list['id'], 'label' => $list['name'] ); } } return array( 'heading' => substr( Sendtim_Forms::input( $input, 'heading' ), 0, 500 ), 'description' => substr( Sendtim_Forms::input( $input, 'description' ), 0, 500 ), 'list_id' => $list_id, 'interests' => $interests, 'editor_fields' => $editor, 'definition' => array( 'fields' => $fields, 'style' => array( 'accentColor' => sanitize_hex_color( Sendtim_Forms::input( $input, 'accent' ) ) ?: '#4f46e5', 'borderRadius' => 12, 'width' => 480, 'buttonLabel' => $button, 'layout' => 'inline' === Sendtim_Forms::input( $input, 'layout' ) ? 'inline' : 'stacked' ), 'settings' => array( 'successBehavior' => array( 'kind' => 'message', 'text' => $success ) ), ) ); } public static function delete() { $id = absint( Sendtim_Forms::input( $_POST, 'id' ) ); self::guard( 'sendtim_forms_delete_' . $id ); $post = get_post( $id ); if ( ! $post || Sendtim_Forms::TYPE !== $post->post_type ) { self::redirect( 'error' ); } wp_delete_post( $id, true ); self::redirect( 'deleted' ); } }