'Dataverse (Generic)', 'tasks' => array( 'create_record' => __( 'Create Record in any table', 'advanced-form-integration' ), ), ); return $actions; } public function register_settings_tab( $providers ) { $providers['dataverse'] = 'Dataverse (Generic)'; return $providers; } public function settings_view( $current_tab ) { if ( 'dataverse' !== $current_tab ) { return; } $crm_url = admin_url( 'admin.php?page=advanced-form-integration-settings&tab=dynamics365' ); ?>

Dynamics 365 CRM — there\'s nothing to configure here.', 'advanced-form-integration' ), array( 'a' => array( 'href' => array() ) ) ), esc_url( $crm_url ) ); ?>


__( 'Security check failed', 'advanced-form-integration' ) ) ); } $cred_id = isset( $_POST['credId'] ) ? sanitize_text_field( wp_unslash( $_POST['credId'] ) ) : ''; if ( ! $cred_id ) { wp_send_json_error( array( 'message' => __( 'Missing credential id', 'advanced-form-integration' ) ) ); } if ( ! class_exists( 'ADFOIN_Dynamics365' ) ) { wp_send_json_error( array( 'message' => __( 'Dynamics 365 connection module is not loaded.', 'advanced-form-integration' ) ) ); } $cache_key = 'adfoin_dataverse_entities_' . md5( $cred_id ); $cached = get_transient( $cache_key ); if ( is_array( $cached ) ) { wp_send_json_success( $cached ); } $d = ADFOIN_Dynamics365::get_instance(); $d->set_credentials( $cred_id ); $endpoint = 'EntityDefinitions?' . http_build_query( array( '$select' => 'LogicalName,EntitySetName,DisplayName', '$filter' => 'IsValidForCreate eq true', ) ); $response = $d->dynamics365_request( $endpoint, 'GET' ); if ( is_wp_error( $response ) ) { wp_send_json_error( array( 'message' => $response->get_error_message() ) ); } $code = (int) wp_remote_retrieve_response_code( $response ); if ( 200 !== $code ) { $body = json_decode( wp_remote_retrieve_body( $response ), true ); $msg = is_array( $body ) && isset( $body['error']['message'] ) ? $body['error']['message'] : sprintf( 'HTTP %d', $code ); wp_send_json_error( array( 'message' => $msg ) ); } $body = json_decode( wp_remote_retrieve_body( $response ), true ); $entities = array(); if ( ! empty( $body['value'] ) && is_array( $body['value'] ) ) { foreach ( $body['value'] as $e ) { $set = $e['EntitySetName'] ?? ''; if ( ! $set ) { continue; } $label = $e['DisplayName']['UserLocalizedLabel']['Label'] ?? ''; if ( ! $label ) { $label = $e['LogicalName'] ?? $set; } $entities[ $set ] = $label . ' (' . $set . ')'; } // Sort by entity-set name for a stable list. ksort( $entities ); } set_transient( $cache_key, $entities, 6 * HOUR_IN_SECONDS ); wp_send_json_success( $entities ); } } ADFOIN_Dataverse::get_instance(); /* ---------- Dispatch ---------- */ function adfoin_dataverse_job_queue( $data ) { if ( ! isset( $data['record'], $data['posted_data'] ) ) { return; } adfoin_dataverse_send_data( $data['record'], $data['posted_data'] ); } add_action( 'adfoin_dataverse_job_queue', 'adfoin_dataverse_job_queue', 10, 1 ); add_action( 'adfoin_job_queue', 'adfoin_dataverse_job_queue', 10, 1 ); function adfoin_dataverse_send_data( $record, $posted_data ) { $record_data = json_decode( $record['data'], true ); if ( isset( $record_data['action_data']['cl'] ) && function_exists( 'adfoin_check_conditional_logic' ) && adfoin_check_conditional_logic( $record_data['action_data']['cl'], $posted_data ) ) { return; } $field_data = isset( $record_data['field_data'] ) ? $record_data['field_data'] : $record_data; $cred_id = $field_data['credId'] ?? ( $record['cred_id'] ?? '' ); $entity_set = $field_data['entitySet'] ?? ''; $rows = isset( $field_data['rows'] ) && is_array( $field_data['rows'] ) ? $field_data['rows'] : array(); $lookups = isset( $field_data['lookups'] ) && is_array( $field_data['lookups'] ) ? $field_data['lookups'] : array(); $task = $record['task'] ?? ''; if ( ! $cred_id || 'create_record' !== $task ) { return; } if ( ! $entity_set ) { return; } if ( ! class_exists( 'ADFOIN_Dynamics365' ) ) { return; } // Sanitize entity-set name — allow alphanumeric + underscore only. Stops // OData injection (..) and forces a clean table name. $entity_set = preg_replace( '/[^a-z0-9_]/i', '', $entity_set ); if ( ! $entity_set ) { return; } $d = ADFOIN_Dynamics365::get_instance(); $d->set_credentials( $cred_id ); if ( ! $d->ensure_token() ) { return; } // Build payload from row-style mappings. $payload = array(); foreach ( $rows as $row ) { if ( ! is_array( $row ) ) { continue; } $key = isset( $row['key'] ) ? sanitize_key( wp_unslash( $row['key'] ) ) : ''; if ( '' === $key ) { continue; } $raw = isset( $row['value'] ) ? wp_unslash( $row['value'] ) : ''; $val = adfoin_get_parsed_values( $raw, $posted_data ); if ( $val === '' || $val === null ) { continue; } // Type-coerce common patterns. We don't have entity metadata // here, so this is best-effort: digits-only stays string, // 'true'/'false' becomes bool, ISO-ish dates stay as strings // (Dynamics accepts them via OData). $lower = strtolower( (string) $val ); if ( $lower === 'true' ) { $val = true; } elseif ( $lower === 'false' ) { $val = false; } $payload[ $key ] = $val; } // Lookup bindings — user supplies field name, target entity set, and // the GUID. We render @odata.bind for each. foreach ( $lookups as $row ) { if ( ! is_array( $row ) ) { continue; } $field = isset( $row['field'] ) ? sanitize_key( wp_unslash( $row['field'] ) ) : ''; $target = isset( $row['entitySet'] ) ? preg_replace( '/[^a-z0-9_]/i', '', wp_unslash( $row['entitySet'] ) ) : ''; if ( ! $field || ! $target ) { continue; } $raw = isset( $row['value'] ) ? wp_unslash( $row['value'] ) : ''; $guid = adfoin_get_parsed_values( $raw, $posted_data ); $guid = trim( $guid, "{} \t\n\r\0\x0B" ); if ( ! $guid ) { continue; } $payload[ $field . '@odata.bind' ] = '/' . $target . '(' . $guid . ')'; } if ( empty( $payload ) ) { return; } $d->dynamics365_request( $entity_set, 'POST', $payload, $record ); }