: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
namespace WPForms\Admin\Tools\Importers;
use WPForms\Helpers\PluginSilentUpgrader;
use WPForms\Helpers\PluginSilentUpgraderSkin;
* Pirate Forms Importer class.
class PirateForms extends Base {
* Direct URL to download the latest version of WP Mail SMTP plugin from WP.org repo.
const URL_SMTP_ZIP = 'https://downloads.wordpress.org/plugin/wp-mail-smtp.zip';
* WP Mail SMTP plugin basename.
const SLUG_SMTP_PLUGIN = 'wp-mail-smtp/wp_mail_smtp.php';
* Default PirateForms smart tags.
* Define required properties.
$this->name = 'Pirate Forms';
$this->slug = 'pirate-forms';
$this->path = 'pirate-forms/pirate-forms.php';
* We need only ID's and names here.
public function get_forms() {
// Union those arrays, as array_merge() does keys reindexing.
$forms = $this->get_default_forms() + $this->get_pro_forms();
* Pirate Forms has a default form, which doesn't have an ID.
protected function get_default_forms() {
$form = \PirateForms_Util::get_form_options();
// Just make sure that it's there and not broken.
return [ 0 => esc_html__( 'Default Form', 'wpforms-lite' ) ];
* Copy-paste from Pro plugin code, it doesn't have API to get this data easily.
protected function get_pro_forms() {
'post_type' => 'pf_form',
'post_status' => 'publish',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$forms[ get_the_ID() ] = get_the_title();
* Get a single form options.
* @param int $id Form ID.
public function get_form( $id ) {
return \PirateForms_Util::get_form_options( (int) $id );
* Import a single form using AJAX.
public function import_form() {
check_ajax_referer( 'wpforms-admin', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can( 'create_forms' ) ) {
$analyze = isset( $_POST['analyze'] );
$pf_form_id = isset( $_POST['form_id'] ) ? (int) $_POST['form_id'] : 0;
$pf_form = $this->get_form( $pf_form_id );
$pf_fields_custom = \PirateForms_Util::get_post_meta( $pf_form_id, 'custom' );
$fields_pro_plain = [ 'tel' ]; // Convert them in Lite to the closest Standard alternatives.
$fields_pro_omit = [ 'label', 'file', 'attachment' ]; // Strict PRO fields with no Lite alternatives.
if ( ! empty( $pf_fields_custom[0] ) ) {
$pf_fields_custom = $pf_fields_custom[0];
if ( empty( $pf_form_id ) ) {
$pf_form_name = esc_html__( 'Default Form', 'wpforms-lite' );
$pf_form_name = get_post_field( 'post_title', $pf_form_id );
$pf_form_name = wpforms_decode_string( apply_filters( 'the_title', $pf_form_name, $pf_form_id ) );
// Prepare all DEFAULT fields.
foreach ( $pf_fields_default as $field ) {
// Ignore fields that are not displayed or not added at all.
if ( empty( $pf_form[ 'pirateformsopt_' . $field . '_field' ] ) ) {
// Ignore certain fields as they are dealt with later.
if ( $field === 'recaptcha' ) {
$required = $pf_form[ 'pirateformsopt_' . $field . '_field' ] === 'req' ? '1' : '';
$label = ! empty( $pf_form[ 'pirateformsopt_label_' . $field ] ) ? $pf_form[ 'pirateformsopt_label_' . $field ] : ucwords( $field );
// If it is Lite and it's a field type not included, make a note then continue to the next field.
if ( ! wpforms()->is_pro() && in_array( $field, $fields_pro_plain, true ) ) {
$upgrade_plain[] = $label;
if ( ! wpforms()->is_pro() && in_array( $field, $fields_pro_omit, true ) ) {
$upgrade_omit[] = $label;
// Determine next field ID to assign.
if ( empty( $fields ) ) {
$field_id = (int) max( array_keys( $fields ) ) + 1;
// Separately process certain fields.
if ( $field === 'subject' ) {
} elseif ( $field === 'message' ) {
if ( $field === 'name' ) {
$fields[ $field_id ]['format'] = 'simple';
'label' => esc_html__( 'Single Checkbox Field', 'wpforms-lite' ),
// If PF attachments were saved into FS, we need to save them in WP Media.
// That will allow admins to easily delete if needed.
! empty( $pf_form['pirateformsopt_save_attachment'] ) &&
$pf_form['pirateformsopt_save_attachment'] === 'yes'
$fields[ $field_id ]['media_library'] = true;
// Prepare all CUSTOM fields.
foreach ( $pf_fields_custom as $id => $field ) {
// Ignore fields that are not displayed.
if ( empty( $field['display'] ) ) {
$required = $field['display'] === 'req' ? '1' : ''; // Possible values in PF: 'yes', 'req'.
$label = sanitize_text_field( $field['label'] );
// If it is Lite and it's a field type not included, make a note then continue to the next field.
if ( ! wpforms()->is_pro() && in_array( $field['type'], $fields_pro_plain, true ) ) {
$upgrade_plain[] = $label;
if ( ! wpforms()->is_pro() && in_array( $field['type'], $fields_pro_omit, true ) ) {
$upgrade_omit[] = $label;
// Determine next field ID to assign.
if ( empty( $fields ) ) {
$field_id = (int) max( array_keys( $fields ) ) + 1;
switch ( $field['type'] ) {
if ( $field['type'] === 'textarea' ) {
if ( $field['type'] === 'tel' ) {
if ( $field['type'] === 'tel' ) {
$fields[ $field_id ]['format'] = 'international';
'label' => esc_html__( 'Single Checkbox Field', 'wpforms-lite' ),
if ( $field['type'] === 'multiselect' ) {
foreach ( explode( PHP_EOL, $field['options'] ) as $option ) {
'code' => $field['label'],
// If PF attachments were saved into FS, we need to save them in WP Media.
// That will allow admins to easily delete if needed.
! empty( $pf_form['pirateformsopt_save_attachment'] ) &&
$pf_form['pirateformsopt_save_attachment'] === 'yes'
$fields[ $field_id ]['media_library'] = true;
// If we are analyzing the form (in Lite only),
// we can stop here and return the details about this form.
'upgrade_plain' => $upgrade_plain,
'upgrade_omit' => $upgrade_omit,
// Make sure we have imported some fields.
if ( empty( $fields ) ) {
'msg' => esc_html__( 'No form fields found.', 'wpforms-lite' ),
// Create a form array, that holds all the data.
'form_title' => $pf_form_name,
'submit_text' => stripslashes( $pf_form['pirateformsopt_label_submit_btn'] ),
'submit_text_processing' => esc_html__( 'Sending', 'wpforms-lite' ),
'notification_enable' => '1',
'notification_name' => esc_html__( 'Default Notification', 'wpforms-lite' ),
'email' => $pf_form['pirateformsopt_email_recipients'],
'subject' => sprintf( /* translators: %s - form name. */
esc_html__( 'New Entry: %s', 'wpforms-lite' ),
'sender_name' => get_bloginfo( 'name' ),
'sender_address' => $this->get_smarttags( $pf_form['pirateformsopt_email'], $fields ),
'message' => '{all_fields}',
'type' => empty( $pf_form['pirateformsopt_thank_you_url'] ) ? 'message' : 'page',
'page' => (int) $pf_form['pirateformsopt_thank_you_url'],
'message' => ! empty( $pf_form['pirateformsopt_label_submit'] ) ? $pf_form['pirateformsopt_label_submit'] : esc_html__( 'Thanks for contacting us! We will be in touch with you shortly.', 'wpforms-lite' ),
'disable_entries' => $pf_form['pirateformsopt_store'] === 'yes' ? '0' : '1',
'import_form_id' => $pf_form_id,
// Do not save user IP address and UA.
if ( empty( $pf_form['pirateformsopt_store_ip'] ) || $pf_form['pirateformsopt_store_ip'] !== 'yes' ) {
$wpforms_settings = get_option( 'wpforms_settings', [] );
$wpforms_settings['gdpr'] = true;
update_option( 'wpforms_settings', $wpforms_settings );
$form['settings']['disable_ip'] = true;
! empty( $pf_form['pirateformsopt_recaptcha_field'] ) &&
$pf_form['pirateformsopt_recaptcha_field'] === 'yes'
// If the user has already defined v2 reCAPTCHA keys, use those.
$site_key = wpforms_setting( 'recaptcha-site-key', '' );
$secret_key = wpforms_setting( 'recaptcha-secret-key', '' );
// Try to abstract keys from PF.
if ( empty( $site_key ) || empty( $secret_key ) ) {
if ( ! empty( $pf_form['pirateformsopt_recaptcha_sitekey'] ) && ! empty( $pf_form['pirateformsopt_recaptcha_secretkey'] ) ) {
$wpforms_settings = get_option( 'wpforms_settings', [] );
$wpforms_settings['recaptcha-site-key'] = $pf_form['pirateformsopt_recaptcha_sitekey'];