__( 'Notion', 'advanced-form-integration' ), 'tasks' => array( 'add_item' => __( 'Add Database Item', 'advanced-form-integration' ) ) ); return $actions; } add_filter( 'adfoin_settings_tabs', 'adfoin_notion_settings_tab', 10, 1 ); function adfoin_notion_settings_tab( $providers ) { $providers['notion'] = __( 'Notion', 'advanced-form-integration' ); return $providers; } add_action( 'adfoin_settings_view', 'adfoin_notion_settings_view', 10, 1 ); function adfoin_notion_settings_view( $current_tab ) { if( $current_tab != 'notion' ) { return; } if ( ! class_exists( 'ADFOIN_Account_Manager' ) ) { require_once plugin_dir_path( __FILE__ ) . '../../includes/class-adfoin-account-manager.php'; } $fields = array( array( 'name' => 'apiToken', 'label' => __( 'Internal Integration Token', 'advanced-form-integration' ), 'type' => 'text', 'required' => true, 'mask' => true, 'placeholder' => __( 'Enter your Notion integration token', 'advanced-form-integration' ), 'show_in_table' => true ) ); $instructions = sprintf( '
  1. %s
  2. %s
  3. %s
  4. %s
  5. %s
', sprintf( __('Go to %s and click "New integration".', 'advanced-form-integration'), 'https://www.notion.so/my-integrations' ), __('Give your integration a name and select the workspace.', 'advanced-form-integration'), __('Click "Submit" to create the integration.', 'advanced-form-integration'), __('Copy the "Internal Integration Token" and paste it here.', 'advanced-form-integration'), __('Important: Share your databases with the integration by clicking "..." > "Connections" > select your integration.', 'advanced-form-integration') ); ADFOIN_Account_Manager::render_settings_view( 'notion', __( 'Notion', 'advanced-form-integration' ), $fields, $instructions ); } add_action( 'wp_ajax_adfoin_get_notion_credentials', 'adfoin_get_notion_credentials', 10, 0 ); /* * Get Notion credentials */ function adfoin_get_notion_credentials() { if ( ! class_exists( 'ADFOIN_Account_Manager' ) ) { require_once plugin_dir_path( __FILE__ ) . '../../includes/class-adfoin-account-manager.php'; } ADFOIN_Account_Manager::ajax_get_credentials_list( 'notion' ); } add_action( 'wp_ajax_adfoin_save_notion_credentials', 'adfoin_save_notion_credentials', 10, 0 ); /* * Save Notion credentials */ function adfoin_save_notion_credentials() { if ( ! class_exists( 'ADFOIN_Account_Manager' ) ) { require_once plugin_dir_path( __FILE__ ) . '../../includes/class-adfoin-account-manager.php'; } ADFOIN_Account_Manager::ajax_save_credentials( 'notion', array( 'apiToken' ) ); } /* * Notion Credentials List */ function adfoin_notion_get_credentials_list() { $credentials = adfoin_read_credentials( 'notion' ); foreach ($credentials as $option) { printf('', esc_attr($option['id']), esc_html($option['title'])); } } // Legacy single-account import: surfaces old `adfoin_notion_*` options // as a Legacy Account record when the new credentials store is empty. add_action( 'plugins_loaded', function() { if ( class_exists( 'ADFOIN_Account_Manager' ) ) { ADFOIN_Account_Manager::register_legacy_option_importer( 'notion', array( 'apiToken' => 'adfoin_notion_api_token', ) ); } }, 20 ); add_action( 'adfoin_action_fields', 'adfoin_notion_action_fields' ); function adfoin_notion_action_fields() { ?> 30, 'method' => $method, 'headers' => array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $api_token, 'Notion-Version' => '2022-06-28', ), ); if ( 'POST' == $method || 'PATCH' == $method || 'PUT' == $method ) { $args['body'] = wp_json_encode( $data ); } $response = wp_remote_request( $url, $args ); if ( $record ) { adfoin_add_to_log( $response, $url, $args, $record ); } return $response; } add_action( 'wp_ajax_adfoin_get_notion_databases', 'adfoin_get_notion_databases', 10, 0 ); /* * Get Notion Databases */ function adfoin_get_notion_databases() { // Security Check adfoin_verify_nonce(); $cred_id = isset( $_POST['credId'] ) ? sanitize_text_field( wp_unslash( $_POST['credId'] ) ) : ''; $search_data = array( 'filter' => array( 'value' => 'database', 'property' => 'object' ), 'sort' => array( 'direction' => 'descending', 'timestamp' => 'last_edited_time' ) ); $all_databases = array(); $has_more = true; $start_cursor = null; while ( $has_more ) { if ( $start_cursor ) { $search_data['start_cursor'] = $start_cursor; } $response = adfoin_notion_request( 'search', 'POST', $search_data, array(), $cred_id ); if ( is_wp_error( $response ) ) { wp_send_json_error(); } $body = json_decode( wp_remote_retrieve_body( $response ), true ); if ( isset( $body['results'] ) && is_array( $body['results'] ) ) { foreach ( $body['results'] as $database ) { if ( isset( $database['id'] ) ) { $title = ''; if ( isset( $database['title'] ) && is_array( $database['title'] ) ) { foreach ( $database['title'] as $title_part ) { if ( isset( $title_part['plain_text'] ) ) { $title .= $title_part['plain_text']; } } } $all_databases[ $database['id'] ] = $title ? $title : __( 'Untitled', 'advanced-form-integration' ); } } } $has_more = isset( $body['has_more'] ) ? $body['has_more'] : false; $start_cursor = isset( $body['next_cursor'] ) ? $body['next_cursor'] : null; // Limit to prevent infinite loops if ( count( $all_databases ) > 500 ) { break; } } wp_send_json_success( $all_databases ); } add_action( 'wp_ajax_adfoin_get_notion_fields', 'adfoin_get_notion_fields', 10, 0 ); /* * Get Notion Database Fields/Properties */ function adfoin_get_notion_fields() { // Security Check adfoin_verify_nonce(); $database_id = isset( $_POST['databaseId'] ) ? sanitize_text_field( wp_unslash( $_POST['databaseId'] ) ) : ''; $cred_id = isset( $_POST['credId'] ) ? sanitize_text_field( wp_unslash( $_POST['credId'] ) ) : ''; if ( empty( $database_id ) ) { wp_send_json_error(); } $response = adfoin_notion_request( 'databases/' . $database_id, 'GET', array(), array(), $cred_id ); if ( is_wp_error( $response ) ) { wp_send_json_error(); } $body = json_decode( wp_remote_retrieve_body( $response ), true ); $fields = array(); // Supported property types in basic version $supported_types = array( 'title', 'rich_text', 'number', 'select', 'checkbox', 'date', 'email', 'phone_number', 'url' ); if ( isset( $body['properties'] ) && is_array( $body['properties'] ) ) { foreach ( $body['properties'] as $name => $property ) { $type = isset( $property['type'] ) ? $property['type'] : ''; if ( ! in_array( $type, $supported_types ) ) { continue; } $description = adfoin_notion_get_field_description( $property ); $fields[] = array( 'key' => $type . '__' . $name, 'value' => $name, 'description' => $description ); } } wp_send_json_success( $fields ); } /* * Get field description based on property type */ function adfoin_notion_get_field_description( $property ) { $type = isset( $property['type'] ) ? $property['type'] : ''; $description = ''; switch ( $type ) { case 'title': $description = __( 'Required. The title of the database item.', 'advanced-form-integration' ); break; case 'rich_text': $description = __( 'Text content.', 'advanced-form-integration' ); break; case 'number': $description = __( 'Numeric value.', 'advanced-form-integration' ); break; case 'select': if ( isset( $property['select']['options'] ) && is_array( $property['select']['options'] ) ) { $options = wp_list_pluck( $property['select']['options'], 'name' ); if ( ! empty( $options ) ) { $description = sprintf( __( 'Options: %s', 'advanced-form-integration' ), implode( ', ', $options ) ); } } break; case 'checkbox': $description = __( 'Use "true", "yes", or "1" to check. Anything else unchecks.', 'advanced-form-integration' ); break; case 'date': $description = __( 'Date in ISO 8601 format (e.g., 2024-01-15 or 2024-01-15T10:30:00).', 'advanced-form-integration' ); break; case 'email': $description = __( 'Email address.', 'advanced-form-integration' ); break; case 'phone_number': $description = __( 'Phone number.', 'advanced-form-integration' ); break; case 'url': $description = __( 'URL/Link.', 'advanced-form-integration' ); break; } return $description; } add_action( 'adfoin_notion_job_queue', 'adfoin_notion_job_queue', 10, 1 ); function adfoin_notion_job_queue( $data ) { adfoin_notion_send_data( $data['record'], $data['posted_data'] ); } /* * Handles sending data to Notion API */ function adfoin_notion_send_data( $record, $posted_data ) { $record_data = json_decode( $record['data'], true ); if ( adfoin_check_conditional_logic( $record_data['action_data']['cl'] ?? array(), $posted_data ) ) { return; } $data = $record_data['field_data']; $database_id = isset( $data['databaseId'] ) ? $data['databaseId'] : ''; $cred_id = isset( $data['credId'] ) ? $data['credId'] : ''; $task = $record['task']; // Backward compatibility: if no cred_id, use first available credential if ( empty( $cred_id ) ) { $all_credentials = adfoin_read_credentials( 'notion' ); if ( ! empty( $all_credentials ) ) { $cred_id = $all_credentials[0]['id']; } } if ( empty( $database_id ) ) { return; } if ( $task == 'add_item' ) { // Remove non-field data unset( $data['databaseId'] ); unset( $data['databases'] ); unset( $data['credId'] ); $properties = array(); foreach ( $data as $key => $value ) { if ( empty( $value ) ) { continue; } $parsed_value = adfoin_get_parsed_values( $value, $posted_data ); $parsed_value_trimmed = is_string( $parsed_value ) ? trim( $parsed_value ) : $parsed_value; if ( '' === $parsed_value_trimmed ) { continue; } $field_parts = explode( '__', $key, 2 ); if ( count( $field_parts ) < 2 ) { continue; } list( $field_type, $field_name ) = $field_parts; $formatted_property = adfoin_notion_format_property( $field_type, $parsed_value ); if ( null !== $formatted_property ) { $properties[ $field_name ] = $formatted_property; } } if ( empty( $properties ) ) { return; } $page_data = array( 'parent' => array( 'database_id' => $database_id ), 'properties' => $properties ); $response = adfoin_notion_request( 'pages', 'POST', $page_data, $record, $cred_id ); } return; } /* * Format property value for Notion API */ function adfoin_notion_format_property( $type, $value ) { if ( is_string( $value ) ) { $value = trim( $value ); } switch ( $type ) { case 'title': return array( 'title' => array( array( 'text' => array( 'content' => $value ) ) ) ); case 'rich_text': return array( 'rich_text' => array( array( 'text' => array( 'content' => $value ) ) ) ); case 'number': if ( ! is_numeric( $value ) ) { return null; } return array( 'number' => floatval( $value ) ); case 'select': return array( 'select' => array( 'name' => $value ) ); case 'checkbox': $bool_value = in_array( strtolower( $value ), array( 'true', 'yes', '1', 'on' ), true ); return array( 'checkbox' => $bool_value ); case 'date': // Try to parse the date $timestamp = strtotime( $value ); if ( false === $timestamp ) { return null; } return array( 'date' => array( 'start' => date( 'Y-m-d', $timestamp ) ) ); case 'email': return array( 'email' => $value ); case 'phone_number': return array( 'phone_number' => $value ); case 'url': return array( 'url' => $value ); } return null; }