<?php
/**
 * Add database update notice hook
 */
add_action( 'admin_init', 'wpj_db_update_todo_notices', 9 );
function wpj_db_update_todo_notices() {
	if ( get_option( 'wpjobster_installed_date' ) ) {

		$todo = apply_filters( 'wpj_db_update_array_filter', [] );

		foreach ( $todo as $todo_id => $todo_description ) {
			if ( get_option( $todo_id ) != 'done' ) {

				add_action( 'admin_notices', function() use ( $todo_id, $todo_description ) {

					echo '<div class="error notice">'
						. '<h2>' . __( 'Jobster Database update required!', 'wpjobster' )
							. ' <a class="page-title-action" href="' . admin_url( 'admin.php?page=dg-batches&action=view&id=' . $todo_id ) . '">' . __( 'Update Now', 'wpjobster' ) . '</a>'
						. '</h2>'
						. '<p>' . $todo_description . '</p>'
					. '</div>';

				}, 9 );
			}
		}

		global $pagenow;
		// hide all notices on the database update page
		if ( isset( $_GET['page'] ) && is_admin() && ( 'admin.php' === $pagenow && 'dg-batches' === $_GET['page'] ) ) {
			remove_all_actions( 'admin_notices' );
		}

	}
}

/**
 * Hide wp-batch-processing plugin menu
 */
add_action( 'admin_menu', 'wpj_batch_processing_remove_menu' );
function wpj_batch_processing_remove_menu() {
	remove_menu_page( 'dg-batches' );
}

/**
 * Change wp-batch-processing plugin success message
 */
add_filter( 'dg_batch_finished_message', 'wpj_dg_batch_finished_message' );
function wpj_dg_batch_finished_message( $message ) {

	$message = __( 'Processing finished. You can exit this page now.', 'wpjobster' ) . '<br><a href="' . get_admin_url() . 'admin.php?page=jobster-settings' . '">' . __( 'Jobster Dashboard', 'wpjobster' ) . '</a>';

	return $message;
}

/**
 * Batches description
 */
add_filter( 'wpj_db_update_array_filter', function( $todo ) {

	$todo['wpj_batch_update_6_metas'] = 'This tool updates the Featured section of the job page of the dashboard with the first image of the job.';

	$todo['wpj_batch_update_user_2fa_meta'] = 'If 2FA is enabled for your site, this tool updates the user option to be enabled by default, and the user has the option to later disable 2FA for their account.';

	$todo['wpj_batch_update_job_reviews_meta'] = 'This tool updates the job_reviews meta for published jobs, which helps when sorting by reviews is involved.';

	return $todo;

}, 15, 1 );

/**
 * Batch #1
 * Updates the Featured section with the first image of the job
 */
if ( class_exists( 'WP_Batch' ) ) {

	/**
	 * Class WPJ_Batch_Update_6
	 */
	class WPJ_Batch_Update_6 extends WP_Batch {

		/**
		 * Unique identifier of each batch
		 * @var string
		 */
		public $id = 'wpj_batch_update_6_metas';

		/**
		 * Describe the batch
		 * @var string
		 */
		public $title = 'Updates the Featured section with the first image of the job';

		/**
		 * Describe the batch
		 * @var string
		 */
		public $description = '<p>This tool updates the Featured section of the job page of the dashboard with the first image of the job.</p>';

		/**
		 * To setup the batch data use the push() method to add WP_Batch_Item instances to the queue.
		 *
		 * Note: If the operation of obtaining data is expensive, cache it to avoid slowdowns.
		 *
		 * @return void
		 */
		public function setup() {
			global $wpdb;

			$null_post_metas = $wpdb->get_results(
				"
				SELECT * FROM {$wpdb->prefix}posts
				WHERE post_type = 'job' AND post_status != 'auto-draft'
				ORDER BY post_date DESC
				", ARRAY_A
			);

			foreach ( $null_post_metas as $null_post_meta ) {
				$this->push( new WP_Batch_Item( $null_post_meta['ID'], [ 'post_id' => $null_post_meta['ID'] ] ) );
			}
		}

		/**
		 * Handles processing of batch item. One at a time.
		 *
		 * In order to work it correctly you must return values as follows:
		 *
		 * - TRUE - If the item was processed successfully.
		 * - WP_Error instance - If there was an error. Add message to display it in the admin area.
		 *
		 * @param WP_Batch_Item $item
		 *
		 * @return bool|\WP_Error
		 */
		public function process( $item ) {

			// Retrieve the custom data
			$post_id = $item->get_value( 'post_id' );

			// Return WP_Error if the item processing failed
			if ( ! $post_id ) {
				return new WP_Error( 302, "Invalid item" );
			}

			// Do the expensive processing here.
			$attachments = wpj_get_job_images( $post_id );
			if ( $attachments ) set_post_thumbnail( $post_id, $attachments[0]->ID );

			// Return true if the item processing is successful.
			return true;
		}

		/**
		 * Called when specific process is finished (all items were processed).
		 * This method can be overriden in the process class.
		 * @return void
		 */
		public function finish() {
			// Do something after process is finished.
			// You have $this->items, etc.
			update_option( $this->id, 'done' );
			add_action( 'admin_notices', 'wpj_database_updated_notice', 9 );
		}
	}
}

add_action( 'wp_batch_processing_init', function() {
	$batch = new WPJ_Batch_Update_6();
	WP_Batch_Processor::get_instance()->register( $batch );

	// exit if nothing to do
	if ( $batch->id == WPJ_Form::get( 'id' ) && $batch->get_items_count() == 0 && ! wp_doing_ajax() ) {
		$batch->finish();
		wp_redirect( get_admin_url() . 'admin.php?page=jobster-settings' );
	}
}, 15, 1 );

/**
 * Batch #2
 * Update user 2FA meta
 */
if ( class_exists( 'WP_Batch' ) ) {

	/**
	 * Class WPJ_Batch_Update_User_2FA
	 */
	class WPJ_Batch_Update_User_2FA extends WP_Batch {

		/**
		 * Unique identifier of each batch
		 * @var string
		 */
		public $id = 'wpj_batch_update_user_2fa_meta';

		/**
		 * Describe the batch
		 * @var string
		 */
		public $title = 'Update user 2FA activation meta';

		/**
		 * Describe the batch
		 * @var string
		 */
		public $description = '<p>If 2FA is enabled for your site, this tool updates the user option to be enabled by default, and the user has the option to later disable 2FA for their account.</p>';

		/**
		 * To setup the batch data use the push() method to add WP_Batch_Item instances to the queue.
		 *
		 * Note: If the operation of obtaining data is expensive, cache it to avoid slowdowns.
		 *
		 * @return void
		 */
		public function setup() {
			$all_users = get_users();

			foreach ( $all_users as $null_user_meta ) {
				$this->push( new WP_Batch_Item( $null_user_meta->ID, [ 'user_id' => $null_user_meta->ID ] ) );
			}
		}

		/**
		 * Handles processing of batch item. One at a time.
		 *
		 * In order to work it correctly you must return values as follows:
		 *
		 * - TRUE - If the item was processed successfully.
		 * - WP_Error instance - If there was an error. Add message to display it in the admin area.
		 *
		 * @param WP_Batch_Item $item
		 *
		 * @return bool|\WP_Error
		 */
		public function process( $item ) {

			// Retrieve the custom data
			$user_id = $item->get_value( 'user_id' );

			// Return WP_Error if the item processing failed
			if ( ! $user_id ) {
				return new WP_Error( 302, "Invalid item" );
			}

			// Do the expensive processing here.
			if ( wpj_get_option( 'wpjobster_enable_user_2fa' ) == 'yes' )
				update_user_meta( $user_id, 'user_2fa', 'on' );
			else
				update_user_meta( $user_id, 'user_2fa', 'off' );

			// Return true if the item processing is successful.
			return true;
		}

		/**
		 * Called when specific process is finished (all items were processed).
		 * This method can be overriden in the process class.
		 * @return void
		 */
		public function finish() {
			// Do something after process is finished.
			// You have $this->items, etc.
			update_option( $this->id, 'done' );
			add_action( 'admin_notices', 'wpj_database_updated_notice', 9 );
		}
	}
}

add_action( 'wp_batch_processing_init', function() {
	$batch = new WPJ_Batch_Update_User_2FA();
	WP_Batch_Processor::get_instance()->register( $batch );

	// exit if nothing to do
	if ( $batch->id == WPJ_Form::get( 'id' ) && $batch->get_items_count() == 0 && ! wp_doing_ajax() ) {
		$batch->finish();
		wp_redirect( get_admin_url() . 'admin.php?page=jobster-settings' );
	}
}, 15, 1 );

/**
 * Batch #3
 * Update job_reviews meta to sort jobs by reviews number
 */
if ( class_exists( 'WP_Batch' ) ) {

	/**
	 * Class WPJ_Batch_Update_Job_Reviews_Meta
	 */
	class WPJ_Batch_Update_Job_Reviews_Meta extends WP_Batch {

		/**
		 * Unique identifier of each batch
		 * @var string
		 */
		public $id = 'wpj_batch_update_job_reviews_meta';

		/**
		 * Describe the batch
		 * @var string
		 */
		public $title = 'Update job_reviews meta to sort jobs by reviews number';

		/**
		 * Describe the batch
		 * @var string
		 */
		public $description = '<p>This tool updates the job_reviews meta for published jobs, which helps when sorting by reviews is involved.</p>';

		/**
		 * To setup the batch data use the push() method to add WP_Batch_Item instances to the queue.
		 *
		 * Note: If the operation of obtaining data is expensive, cache it to avoid slowdowns.
		 *
		 * @return void
		 */
		public function setup() {
			global $wpdb;

			$null_post_metas = $wpdb->get_results(
				"
				SELECT * FROM {$wpdb->prefix}posts
				WHERE post_type = 'job' AND post_status != 'auto-draft'
				ORDER BY post_date DESC
				", ARRAY_A
			);

			foreach ( $null_post_metas as $null_post_meta ) {
				$this->push( new WP_Batch_Item( $null_post_meta['ID'], ['post_id' => $null_post_meta['ID']] ) );
			}
		}

		/**
		 * Handles processing of batch item. One at a time.
		 *
		 * In order to work it correctly you must return values as follows:
		 *
		 * - TRUE - If the item was processed successfully.
		 * - WP_Error instance - If there was an error. Add message to display it in the admin area.
		 *
		 * @param WP_Batch_Item $item
		 *
		 * @return bool|\WP_Error
		 */
		public function process( $item ) {

			// Retrieve the custom data
			$post_id = $item->get_value( 'post_id' );

			// Return WP_Error if the item processing failed
			if ( ! $post_id ) {
				return new WP_Error( 302, "Invalid item" );
			}

			// Do the expensive processing here.
			update_post_meta( $post_id, 'job_reviews', wpj_get_job_reviews_number( $post_id ) );

			// Return true if the item processing is successful.
			return true;
		}

		/**
		 * Called when specific process is finished (all items were processed).
		 * This method can be overriden in the process class.
		 * @return void
		 */
		public function finish() {
			// Do something after process is finished.
			// You have $this->items, etc.
			update_option( $this->id, 'done' );
			add_action( 'admin_notices', 'wpj_database_updated_notice', 9 );
		}
	}
}

add_action( 'wp_batch_processing_init', function() {
	$batch = new WPJ_Batch_Update_Job_Reviews_Meta();
	WP_Batch_Processor::get_instance()->register( $batch );

	// exit if nothing to do
	if ( $batch->id == WPJ_Form::get( 'id' ) && $batch->get_items_count() == 0 && ! wp_doing_ajax() ) {
		$batch->finish();
		wp_redirect( get_admin_url() . 'admin.php?page=jobster-settings' );
	}
}, 15, 1 );