Builder::upsert( TECEventsCustom_TablesV1Modelsarray $unique_by, TECEventsCustom_TablesV1Modelsarray|null $data = null )

Insert a new row or update one if already exists.


Parameters

$unique_by

(<span class="TECEventsCustom_TablesV1Modelsarray">TECEventsCustom_TablesV1Modelsarray) (Required) A list of columns that are marked as UNIQUE on the database.

$data

(<span class="TECEventsCustom_TablesV1Modelsarray">TECEventsCustom_TablesV1Modelsarray|null) (Optional) The data to be inserted or updated into the table.

Default value: null


Top ↑

Return

(false|int) The rows affected flag or false on failure.


Top ↑

Source

File: src/Events/Custom_Tables/V1/Models/Builder.php

	public function upsert( array $unique_by, array $data = null ) {
		if ( empty( $unique_by ) ) {
			throw new InvalidArgumentException( 'A series of unique column needs to be specified.' );
		}

		// If no input was provided use the model as input.
		if ( $data === null ) {
			$model = $this->set_data_to_model();
			$model->validate();
		} else {
			if ( empty( $data ) ) {
				return false;
			}

			$columns = array_keys( $data );
			// Make sure the required key is part of the data to be inserted in.
			foreach ( $unique_by as $column ) {
				if ( ! in_array( $column, $columns, true ) ) {
					throw new InvalidArgumentException( "The column '{$column}' must be part of the data array" );
				}
			}

			$model = $this->set_data_to_model( $data );
			$model->validate( array_keys( $data ) );
		}

		if ( $model->is_invalid() ) {
			do_action( 'tribe_log', 'error', implode( ' : ', $model->errors() ), [
				'method' => __METHOD__,
				'line'   => __LINE__,
				'model'  => get_class( $model )
			] );

			return false;
		}

		list( $formatted_data, $format ) = $model->format();

		// No data to be inserted.
		if ( empty( $formatted_data ) ) {
			return false;
		}

		$placeholder_values = $this->create_placeholders( $formatted_data, $format );

		if ( empty( $placeholder_values ) ) {
			return false;
		}

		global $wpdb;

		$update_sql   = [];
		$update_value = [];
		foreach ( $formatted_data as $column => $value ) {
			if ( in_array( $column, $unique_by, true ) ) {
				continue;
			}
			$value_placeholder = isset( $format[ $column ] ) ? $format[ $column ] : '%s';
			$update_sql[]      = "{$column}={$value_placeholder}";
			$update_value[]    = $value;
		}
		$update_assignment_list = $wpdb->prepare( implode( ', ', $update_sql ), ...$update_value );

		$columns = implode( ',', array_keys( $formatted_data ) );

		$SQL = "INSERT INTO {$wpdb->prefix}{$this->model->table_name()} ($columns) VALUES($placeholder_values) ON DUPLICATE KEY update {$update_assignment_list}";
		$SQL = $wpdb->prepare( $SQL, ...$this->create_replacements_values( $formatted_data ) );

		$this->queries[] = $SQL;

		if ( $this->execute_queries && self::$class_execute_queries ) {
			/*
			 * Depending on the db implementation, it could not run updates and return `0`.
			 * We need to make sure it does not return exactly boolean `false`.
			 */
			$result = $wpdb->query( $SQL );
			if ( $result === false ) {
				do_action( 'tribe_log', 'debug', 'Builder: upsert query failure.', [
					'source' => __CLASS__ . ' ' . __METHOD__ . ' ' . __LINE__,
					'trace'  => debug_backtrace( 2, 5 )
				] );
			}

			return $result;
		}

		return 0;
	}

Top ↑

Changelog

Changelog
Version Description
6.1.3 Integration with memoization.
6.0.0 Introduced.