> The option definitions. */ public function options(): array { return array( array( 'key' => 'api_key', 'type' => 'password', 'label' => __( 'API key', 'devplugins-custom-form-builder' ), 'required' => true, // One account key for the site, overridable per form. 'shared' => true, 'description' => __( 'Leave empty to use the key from the Integrations settings.', 'devplugins-custom-form-builder' ), ), array( 'key' => 'list_id', 'type' => 'text', 'label' => __( 'Audience ID', 'devplugins-custom-form-builder' ), 'description' => __( 'A short code such as a1b2c3d4e5.', 'devplugins-custom-form-builder' ), 'required' => true, ), array( 'key' => 'email_field', 'type' => 'field', 'label' => __( 'Email address comes from', 'devplugins-custom-form-builder' ), 'required' => true, ), array( 'key' => 'first_name_field', 'type' => 'field', 'label' => __( 'First name comes from', 'devplugins-custom-form-builder' ), ), array( 'key' => 'last_name_field', 'type' => 'field', 'label' => __( 'Last name comes from', 'devplugins-custom-form-builder' ), ), array( 'key' => 'tags', 'type' => 'text', 'label' => __( 'Tags', 'devplugins-custom-form-builder' ), 'description' => __( 'Comma separated, applied to everyone added through this form.', 'devplugins-custom-form-builder' ), ), array( 'key' => 'double_optin', 'type' => 'checkbox', 'label' => __( 'Ask for confirmation by email', 'devplugins-custom-form-builder' ), 'description' => __( 'Adds the person as pending until they confirm. Leave this on unless the form itself made the consent explicit.', 'devplugins-custom-form-builder' ), ), ); } /** * Returns where a submission should be delivered. * * @param Form $form Form being submitted. * @param array $config Stored values for that form. * * @return Webhook|null The endpoint, or null when there is nothing to send to. */ public function endpoint( Form $form, array $config ): ?Webhook { $key = $this->option( $config, 'api_key' ); $centre = $this->data_centre( $key ); $list = $this->option( $config, 'list_id' ); if ( '' === $centre || '' === $list ) { return null; } return $this->target( sprintf( 'https://%1$s.api.mailchimp.com/3.0/lists/%2$s/members', $centre, rawurlencode( $list ) ), array( // Mailchimp accepts any username with the key as the password. 'Authorization' => 'Basic ' . base64_encode( 'formpilot:' . $key ), ) ); } /** * Determines whether the stored configuration is usable. * * @param array $config Stored values for one form. * * @return bool True when a submission can be sent. */ public function is_configured( array $config ): bool { return parent::is_configured( $config ) && '' !== $this->data_centre( $this->option( $config, 'api_key' ) ); } /** * Builds the member record. * * @param IntegrationContext $context Submission being delivered. * @param array $config Stored values for the form. * * @return array The payload. */ public function payload( IntegrationContext $context, array $config ): array { $merge = array(); $first = $context->value( $this->option( $config, 'first_name_field' ) ); $last = $context->value( $this->option( $config, 'last_name_field' ) ); if ( '' !== $first ) { $merge['FNAME'] = $first; } if ( '' !== $last ) { $merge['LNAME'] = $last; } $payload = array( 'email_address' => $context->email( $this->option( $config, 'email_field' ) ), 'status' => empty( $config['double_optin'] ) ? 'subscribed' : 'pending', ); if ( array() !== $merge ) { $payload['merge_fields'] = $merge; } $tags = array_filter( array_map( 'trim', explode( ',', $this->option( $config, 'tags' ) ) ) ); if ( array() !== $tags ) { $payload['tags'] = array_values( $tags ); } return $payload; } /** * Returns whether a submission has anything worth sending. * * @param IntegrationContext $context Submission being delivered. * @param array $config Stored values for the form. * * @return bool True when the submission carries a usable address. */ public function should_send( IntegrationContext $context, array $config ): bool { return '' !== $context->email( $this->option( $config, 'email_field' ) ); } /** * Returns the data centre an API key belongs to. * * @param string $key API key. * * @return string The subdomain, or an empty string when the key has no suffix. */ private function data_centre( string $key ): string { if ( ! str_contains( $key, '-' ) ) { return ''; } $centre = substr( strrchr( $key, '-' ) ?: '', 1 ); return 1 === preg_match( '/^[a-z0-9]+$/i', $centre ) ? strtolower( $centre ) : ''; } }