'success', 'mail_sent_ng' => 'failed', 'validation_error' => 'invalid', 'spam' => 'spam', 'invalid_required' => 'required', 'invalid_too_long' => 'too_long', 'invalid_too_short' => 'too_short', 'invalid_email' => 'invalid_email', 'invalid_url' => 'invalid_url', 'invalid_tel' => 'invalid_tel', 'invalid_number' => 'invalid_number', 'number_too_small' => 'number_too_small', 'number_too_large' => 'number_too_large', 'invalid_date' => 'invalid_date', 'date_too_early' => 'date_too_early', 'date_too_late' => 'date_too_late', 'upload_failed' => 'upload_failed', 'upload_file_type_invalid' => 'upload_file_type_invalid', 'upload_file_too_large' => 'upload_file_too_large', 'accept_terms' => 'accept_terms', 'quiz_answer_not_correct' => 'quiz_answer_not_correct', ]; // CF7's tags → Remaily's field types const TYPES = [ 'text' => 'text', 'email' => 'email', 'url' => 'url', 'tel' => 'tel', 'number' => 'number', 'range' => 'number', 'date' => 'date', 'textarea' => 'textarea', 'select' => 'select', 'checkbox' => 'checkbox', 'radio' => 'radio', 'acceptance' => 'acceptance', 'quiz' => 'quiz', 'file' => 'file', 'hidden' => 'hidden', 'submit' => 'submit', 'count' => 'count', ]; /** * Init */ public static function init() { add_filter( 'remaily_settings_tabs', [ __CLASS__, 'tab' ] ); add_action( 'admin_post_' . self::ACTION, [ __CLASS__, 'import_request' ] ); // After CF7 would have registered its own add_action( 'init', [ __CLASS__, 'shortcode' ], 20 ); } /** * CF7's forms * * @return \WP_Post[] */ public static function forms() { return get_posts( [ 'post_type' => self::POST_TYPE, 'post_status' => 'any', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC' ] ); } /** * The Import tab, while there are CF7 forms * * @param array $tabs Tabs * * @return array */ public static function tab( array $tabs ) { if ( !self::forms() ) { return $tabs; } return $tabs + [ 'import' => [ 'label' => __( 'Migrate from CF7', 'remaily' ), 'icon' => 'import', 'render' => [ __CLASS__, 'render' ], ], ]; } /** * The Import tab's card */ public static function render() { $imported = self::imported(); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- the result of the import just done $done = absint( $_GET['remaily-imported'] ?? 0 ); ?>
\VLT\Remaily\Admin\Settings::PAGE, 'remaily-imported' => $count ], admin_url( 'admin.php' ) ) . '#import' ); exit; } /** * Import one CF7 form * * @param int $id CF7 form ID * * @return int|\WP_Error The Remaily form's ID */ public static function import( $id ) { $post = get_post( $id ); if ( !$post || self::POST_TYPE !== $post->post_type ) { return new \WP_Error( 'remaily_cf7_missing', __( 'There is no such Contact Form 7 form.', 'remaily' ) ); } $converted = self::convert( (string) get_post_meta( $id, '_form', true ) ); $config = [ 'fields' => $converted['fields'], 'mail' => self::mail( (array) get_post_meta( $id, '_mail', true ), $converted['renamed'] ), 'mail_2' => [ 'active' => !empty( get_post_meta( $id, '_mail_2', true )['active'] ) ] + self::mail( (array) get_post_meta( $id, '_mail_2', true ), $converted['renamed'] ), 'messages' => [], 'settings' => self::settings( (string) get_post_meta( $id, '_additional_settings', true ) ), ]; foreach ( (array) get_post_meta( $id, '_messages', true ) as $key => $text ) { if ( isset( self::MESSAGES[ $key ] ) && is_string( $text ) && '' !== $text ) { $config['messages'][ self::MESSAGES[ $key ] ] = $text; } } $form = wp_insert_post( wp_slash( [ 'post_type' => PostType::NAME, 'post_status' => 'publish', 'post_title' => $post->post_title, 'post_content' => $converted['template'], ] ), true ); if ( is_wp_error( $form ) ) { return $form; } Config::save( $form, $config ); update_post_meta( $form, self::ORIGIN, $id ); do_action( 'remaily_cf7_imported', $form, $id ); return $form; } /** * A CF7 form template as a Remaily template and its fields * * @param string $source CF7's form template * * @return array [ 'template', 'fields' => [ name => settings ], 'renamed' => [ CF7 name => Remaily name ] ] */ public static function convert( $source ) { $fields = []; $renamed = []; $tags = implode( '|', array_merge( array_keys( self::TYPES ), [ 'response' ] ) ); $template = (string) preg_replace_callback( '/\[(' . $tags . ')(\*?)(?:\s+([^\]]*?))?\s*\](?:([^\[]*?)\[\/\1\])?/', static function ( $m ) use ( &$fields, &$renamed ) { $type = $m[1]; if ( 'response' === $type ) { return '[[response]]'; } [ $name, $options, $values ] = self::tokens( (string) ( $m[3] ?? '' ), 'submit' !== $type ); $name = 'submit' === $type ? 'submit' : $name; $safe = strtolower( preg_replace( '/[^\w-]/', '_', (string) $name ) ); $safe = preg_match( '/^[a-z]/', $safe ) ? $safe : 'field_' . $safe; // [count your-message] is named after the field it counts: it gets a name of its own $source = ''; if ( 'count' === $type ) { $source = $safe; $safe .= '_count'; } // A name already taken (two submit buttons): the next free one for ( $base = $safe, $i = 2; isset( $fields[ $safe ] ) || in_array( $safe, Template::reserved(), true ); $i++ ) { $safe = $base . '_' . $i; } if ( $safe !== $name && !in_array( $type, [ 'submit', 'count' ], true ) ) { $renamed[ $name ] = $safe; } $fields[ $safe ] = self::field( self::TYPES[ $type ], '*' === $m[2], $options, $values, trim( (string) ( $m[4] ?? '' ) ) ); if ( 'count' === $type ) { $fields[ $safe ]['source'] = $source; } return '[[' . $safe . ']]'; }, $source ); // The markup as written, without CF7's and
: one line per block, then indented
return [ 'template' => Beautify::html( self::lines( $template ) ), 'fields' => $fields, 'renamed' => $renamed ];
}
/**
* One line per block: the line breaks in a block become spaces, the empty lines between blocks one line break.
*
,