src/properties/class-papi-property-flexible.php
protected function get_results( $value, $repeater_slug, $post_id ) {
		global $wpdb;

		if ( $this->get_meta_type() === 'option' ) {
			$table = $wpdb->prefix . 'options';
			// @codingStandardsIgnoreStart
			$query = $wpdb->prepare(
				"SELECT * FROM `$table` WHERE `option_name` LIKE '%s' ORDER BY `option_id` ASC",
				$repeater_slug . '_%'
			);
			// @codingStandardsIgnoreEnd
		} else {
			$table  = sprintf( '%s%smeta', $wpdb->prefix, $this->get_meta_type() );
			$column = papi_get_meta_id_column( $this->get_meta_type() );
			// @codingStandardsIgnoreStart
			$query = $wpdb->prepare(
				"SELECT * FROM `$table` WHERE `meta_key` LIKE '%s' AND `$column` = %s ORDER BY `meta_id` ASC", $repeater_slug . '_%',
				$post_id
			);
			// @codingStandardsIgnoreEnd
		}

		$dbresults = $wpdb->get_results( $query ); // WPCS: unprepared sql
		$value     = intval( $value );

		// Do not proceed with empty value or columns.
		if ( empty( $value ) ) {
			return [[], []];
		}

		$values  = [];
		$results = [];
		$trash   = [];

		// Get row results.
		$rows = $this->get_row_results( $dbresults );

		// Get columns, divde all items with two.
		$columns = array_map( function ( $row ) {
			return count( $row ) / 2;
		}, $rows );

		$rows = array_values( $rows );

		// Add repeater slug with number of rows to the values array.
		$values[$repeater_slug] = $value;

		for ( $i = 0; $i < $value; $i ++ ) {
			$no_trash = [];

			if ( ! isset( $columns[$i] ) || ! isset( $rows[$i] ) ) {
				continue;
			}

			foreach ( $rows[$i] as $slug => $meta ) {
				if ( ! is_string( $slug ) || ! isset( $rows[$i][$slug] ) ) {
					continue;
				}

				// Do not deal with layout meta object here since the property meta object will deal with it later.
				if ( is_string( $meta->meta_value ) && preg_match( $this->layout_value_regex, $meta->meta_value ) ) {
					if ( ! isset( $values[$slug] ) ) {
						$values[$slug] = $meta->meta_value;
					}

					continue;
				}

				// Add meta object to the no trash array.
				// so it won't be deleted.
				$no_trash[$slug] = $meta;

				// Serialize value if needed.
				$meta->meta_value = papi_maybe_json_decode( maybe_unserialize( $meta->meta_value ) );

				// Add property value and property type value.
				$values[$meta->meta_key] = $meta->meta_value;

				if ( isset( $rows[$i][$slug] ) ) {
					// Add the meta value.
					$values[$slug] = $rows[$i][$slug]->meta_value;
				}
			}

			// Get the meta keys to delete.
			$trash_diff = array_diff( array_keys( $rows[$i] ), array_keys( $no_trash ) );

			if ( ! empty( $trash_diff ) ) {
				// Find all trash meta objects from results array.
				foreach ( $trash_diff as $slug ) {
					if ( ! isset( $results[$i] ) || ! isset( $rows[$i][$slug] ) ) {
						continue;
					}

					$trash[$results[$i][$slug]->meta_key] = $rows[$i][$slug];
				}
			}
		}

		// Fetch one layout per row.
		// Since 3.0.0 this is backward compatibility.
		$dblayouts = [];
		foreach ( array_keys( $values ) as $slug ) {
			if ( $this->is_layout_key( $slug ) ) {
				$num = str_replace( $repeater_slug . '_', '', $slug );
				$num = explode( '_', $num );
				$num = intval( $num[0] );

				if ( ! isset( $dblayouts[$num] ) ) {
					$dblayouts[$num] = $num . $values[$slug];
				}
			}
		}

		$layouts = $this->get_settings_layouts();

		// Add empty rows that isn't saved to database.
		for ( $i = 0; $i < $value; $i ++ ) {
			foreach ( $layouts as $layout ) {
				$layout_slug = sprintf( '%s_%d%s', $this->get_slug( true ), $i, $this->layout_key );

				// Since 3.0.0 the `$dblayouts` check is only for backward compatibility.
				if ( isset( $layout['slug'] ) && ( ( isset( $values[$layout_slug] ) && $layout['slug'] === $values[$layout_slug] ) || in_array( $i . $layout['slug'], $dblayouts, true ) ) ) {
					foreach ( $layout['items'] as $prop ) {
						$slug = sprintf( '%s_%d_%s', $repeater_slug, $i, unpapify( $prop->slug ) );

						if ( ! isset( $values[$slug] ) ) {
							$values[$slug] = null;
						}
					}
				}
			}
		}

		return [$values, $trash];
	}
protected function get_results( $value, $repeater_slug, $post_id ) {
		global $wpdb;

		if ( $this->get_meta_type() === 'option' ) {
			$table = $wpdb->prefix . 'options';
			// @codingStandardsIgnoreStart
			$query = $wpdb->prepare(
				"SELECT * FROM `$table` WHERE `option_name` LIKE '%s' ORDER BY `option_id` ASC",
				$repeater_slug . '_%'
			);
			// @codingStandardsIgnoreEnd
		} else {
			$table  = sprintf( '%s%smeta', $wpdb->prefix, $this->get_meta_type() );
			$column = papi_get_meta_id_column( $this->get_meta_type() );
			// @codingStandardsIgnoreStart
			$query = $wpdb->prepare(
				"SELECT * FROM `$table` WHERE `meta_key` LIKE '%s' AND `$column` = %s ORDER BY `meta_id` ASC", $repeater_slug . '_%',
				$post_id
			);
			// @codingStandardsIgnoreEnd
		}

		$dbresults = $wpdb->get_results( $query ); // WPCS: unprepared sql
		$value     = intval( $value );

		// Do not proceed with empty value or columns.
		if ( empty( $value ) ) {
			return [[], []];
		}

		$values  = [];
		$results = [];
		$trash   = [];

		// Get row results.
		$rows = $this->get_row_results( $dbresults );

		// Get columns, divde all items with two.
		$columns = array_map( function ( $row ) {
			return count( $row ) / 2;
		}, $rows );

		$rows = array_values( $rows );

		// Add repeater slug with number of rows to the values array.
		$values[$repeater_slug] = $value;

		for ( $i = 0; $i < $value; $i ++ ) {
			$no_trash = [];

			if ( ! isset( $columns[$i] ) || ! isset( $rows[$i] ) ) {
				continue;
			}

			foreach ( $rows[$i] as $slug => $meta ) {
				if ( ! is_string( $slug ) || ! isset( $rows[$i][$slug] ) ) {
					continue;
				}

				// Do not deal with layout meta object here since the property meta object will deal with it later.
				if ( is_string( $meta->meta_value ) && preg_match( $this->layout_value_regex, $meta->meta_value ) ) {
					if ( ! isset( $values[$slug] ) ) {
						$values[$slug] = $meta->meta_value;
					}

					continue;
				}

				// Add meta object to the no trash array.
				// so it won't be deleted.
				$no_trash[$slug] = $meta;

				// Serialize value if needed.
				$meta->meta_value = papi_maybe_json_decode( maybe_unserialize( $meta->meta_value ) );

				// Add property value and property type value.
				$values[$meta->meta_key] = $meta->meta_value;

				if ( isset( $rows[$i][$slug] ) ) {
					// Add the meta value.
					$values[$slug] = $rows[$i][$slug]->meta_value;
				}
			}

			// Get the meta keys to delete.
			$trash_diff = array_diff( array_keys( $rows[$i] ), array_keys( $no_trash ) );

			if ( ! empty( $trash_diff ) ) {
				// Find all trash meta objects from results array.
				foreach ( $trash_diff as $slug ) {
					if ( ! isset( $results[$i] ) || ! isset( $rows[$i][$slug] ) ) {
						continue;
					}

					$trash[$results[$i][$slug]->meta_key] = $rows[$i][$slug];
				}
			}
		}

		// Fetch one layout per row.
		// Since 3.0.0 this is backward compatibility.
		$dblayouts = [];
		foreach ( array_keys( $values ) as $slug ) {
			if ( $this->is_layout_key( $slug ) ) {
				$num = str_replace( $repeater_slug . '_', '', $slug );
				$num = explode( '_', $num );
				$num = intval( $num[0] );

				if ( ! isset( $dblayouts[$num] ) ) {
					$dblayouts[$num] = $num . $values[$slug];
				}
			}
		}

		$layouts = $this->get_settings_layouts();

		// Add empty rows that isn't saved to database.
		for ( $i = 0; $i < $value; $i ++ ) {
			foreach ( $layouts as $layout ) {
				$layout_slug = sprintf( '%s_%d%s', $this->get_slug( true ), $i, $this->layout_key );

				// Since 3.0.0 the `$dblayouts` check is only for backward compatibility.
				if ( isset( $layout['slug'] ) && ( ( isset( $values[$layout_slug] ) && $layout['slug'] === $values[$layout_slug] ) || in_array( $i . $layout['slug'], $dblayouts, true ) ) ) {
					foreach ( $layout['items'] as $prop ) {
						$slug = sprintf( '%s_%d_%s', $repeater_slug, $i, unpapify( $prop->slug ) );

						if ( ! isset( $values[$slug] ) ) {
							$values[$slug] = null;
						}
					}
				}
			}
		}

		return [$values, $trash];
	}
Get results from the database.

@param  int    $value
@param  string $repeater_slug
@param  int    $post_id

@return array