__( 'Kintone', 'advanced-form-integration' ), 'tasks' => array( 'create_record' => __( 'Create Record', 'advanced-form-integration' ), ), ); return $actions; } add_filter( 'adfoin_settings_tabs', 'adfoin_kintone_settings_tab', 10, 1 ); function adfoin_kintone_settings_tab( $providers ) { $providers['kintone'] = __( 'Kintone', 'advanced-form-integration' ); return $providers; } add_action( 'adfoin_settings_view', 'adfoin_kintone_settings_view', 10, 1 ); function adfoin_kintone_settings_view( $current_tab ) { if ( 'kintone' !== $current_tab ) { return; } $title = __( 'Kintone', 'advanced-form-integration' ); $key = 'kintone'; $arguments = wp_json_encode( array( 'platform' => $key, 'fields' => array( array( 'key' => 'subdomain', 'label' => __( 'Kintone Subdomain', 'advanced-form-integration' ), 'hidden' => false, 'placeholder' => 'mycompany' ), array( 'key' => 'baseUrl', 'label' => __( 'Custom Base URL (optional)', 'advanced-form-integration' ), 'hidden' => false, 'placeholder' => 'https://mycompany.cybozu.com' ), array( 'key' => 'apiToken', 'label' => __( 'API Token', 'advanced-form-integration' ), 'hidden' => true ), ), ) ); $instructions = sprintf( '
  1. %s
  2. %s
  3. %s
', esc_html__( 'In your Kintone app: Settings → Users & Privileges → API Token. Generate a token with the "Add records" permission.', 'advanced-form-integration' ), esc_html__( 'Subdomain is the part before .kintone.com (e.g. mycompany). For cybozu.com or custom hosts, supply the full Custom Base URL instead.', 'advanced-form-integration' ), esc_html__( 'Each saved credential is per-app: generate a separate token (and AFI credential) for each Kintone app you want to write to.', 'advanced-form-integration' ) ); echo adfoin_platform_settings_template( $title, $key, $arguments, $instructions ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } add_action( 'adfoin_action_fields', 'adfoin_kintone_action_fields' ); function adfoin_kintone_action_fields() { ?> $prop ) { $type = isset( $prop['type'] ) ? (string) $prop['type'] : ''; if ( in_array( $type, $skip_types, true ) ) { continue; } $label = isset( $prop['label'] ) && $prop['label'] !== '' ? $prop['label'] : $code; $fields[] = array( 'key' => $code, 'value' => sprintf( '%s (%s)', $label, $type ), 'description' => isset( $prop['required'] ) && $prop['required'] ? __( 'Required', 'advanced-form-integration' ) : '', 'required' => ! empty( $prop['required'] ), ); } } wp_send_json_success( $fields ); } add_action( 'adfoin_kintone_job_queue', 'adfoin_kintone_job_queue', 10, 1 ); function adfoin_kintone_job_queue( $data ) { adfoin_kintone_send_data( $data['record'], $data['posted_data'] ); } function adfoin_kintone_send_data( $record, $posted_data ) { if ( 'create_record' !== ( $record['task'] ?? '' ) ) { return; } $record_data = json_decode( $record['data'], true ); if ( adfoin_check_conditional_logic( $record_data['action_data']['cl'] ?? array(), $posted_data ) ) { return; } $data = isset( $record_data['field_data'] ) ? $record_data['field_data'] : array(); $cred_id = isset( $data['credId'] ) ? $data['credId'] : ''; $app_id = isset( $data['appId'] ) ? trim( (string) $data['appId'] ) : ''; if ( ! $cred_id || ! $app_id ) { adfoin_add_to_log( new WP_Error( 'kintone_missing_required', __( 'Kintone account or App ID not selected.', 'advanced-form-integration' ) ), '', array(), $record ); return; } $control_keys = array( 'credId', 'appId', 'recordJson' ); $record_body = array(); if ( ! empty( $data['recordJson'] ) ) { $decoded = json_decode( (string) $data['recordJson'], true ); if ( JSON_ERROR_NONE === json_last_error() && is_array( $decoded ) ) { $record_body = $decoded; } } // Wrap each mapped value in Kintone's required `{value: ...}` shape. // Subtables / multi-selects / user-pickers need different shapes — // those should be supplied via the Record JSON escape hatch above. foreach ( $data as $field_code => $value ) { if ( in_array( $field_code, $control_keys, true ) ) { continue; } $parsed = adfoin_get_parsed_values( $value, $posted_data ); if ( '' === $parsed || null === $parsed ) { continue; } $record_body[ $field_code ] = array( 'value' => $parsed ); } if ( empty( $record_body ) ) { return; } $payload = array( 'app' => (int) $app_id, 'record' => $record_body, ); adfoin_kintone_request( 'k/v1/record.json', 'POST', $payload, $record, $cred_id ); } if ( ! function_exists( 'adfoin_kintone_request' ) ) : /** * Kintone REST API request. * * @return array|WP_Error */ function adfoin_kintone_request( $endpoint, $method = 'GET', $data = array(), $record = array(), $cred_id = '' ) { $credentials = adfoin_get_credentials_by_id( 'kintone', $cred_id ); if ( ! $credentials ) { return new WP_Error( 'missing_credentials', __( 'Kintone credentials not found.', 'advanced-form-integration' ) ); } $base = adfoin_kintone_get_base_url( $credentials ); $token = isset( $credentials['apiToken'] ) ? $credentials['apiToken'] : ''; if ( ! $base || ! $token ) { return new WP_Error( 'missing_auth', __( 'Kintone base URL or API token missing.', 'advanced-form-integration' ) ); } $url = trailingslashit( $base ) . ltrim( $endpoint, '/' ); $args = array( 'timeout' => 30, 'method' => $method, 'headers' => array( 'Content-Type' => 'application/json', 'X-Cybozu-API-Token' => $token, ), ); if ( in_array( strtoupper( $method ), array( 'POST', 'PUT', 'PATCH' ), true ) ) { $args['body'] = wp_json_encode( $data ); } $response = wp_remote_request( $url, $args ); if ( $record ) { adfoin_add_to_log( $response, $url, $args, $record ); } return $response; } endif; function adfoin_kintone_get_base_url( $credentials ) { if ( ! empty( $credentials['baseUrl'] ) ) { return untrailingslashit( $credentials['baseUrl'] ); } if ( empty( $credentials['subdomain'] ) ) { return ''; } return 'https://' . trim( $credentials['subdomain'] ) . '.kintone.com'; } function adfoin_kintone_credentials_list() { foreach ( adfoin_read_credentials( 'kintone' ) as $option ) { printf( '', esc_attr( $option['id'] ), esc_html( $option['title'] ) ); } }