InsertTrait.php

Same filename in other branches
  1. 9 core/lib/Drupal/Core/Database/Query/InsertTrait.php
  2. 8.9.x core/lib/Drupal/Core/Database/Query/InsertTrait.php
  3. 10 core/lib/Drupal/Core/Database/Query/InsertTrait.php

Namespace

Drupal\Core\Database\Query

File

core/lib/Drupal/Core/Database/Query/InsertTrait.php

View source
<?php

namespace Drupal\Core\Database\Query;


/**
 * Provides common functionality for INSERT and UPSERT queries.
 *
 * @ingroup database
 */
trait InsertTrait {
    
    /**
     * The table on which to insert.
     *
     * @var string
     */
    protected $table;
    
    /**
     * An array of fields on which to insert.
     *
     * @var array
     */
    protected $insertFields = [];
    
    /**
     * An array of fields that should be set to their database-defined defaults.
     *
     * @var array
     */
    protected $defaultFields = [];
    
    /**
     * A nested array of values to insert.
     *
     * $insertValues is an array of arrays. Each sub-array is either an
     * associative array whose keys are field names and whose values are field
     * values to insert, or a non-associative array of values in the same order
     * as $insertFields.
     *
     * Whether multiple insert sets will be run in a single query or multiple
     * queries is left to individual drivers to implement in whatever manner is
     * most appropriate. The order of values in each sub-array must match the
     * order of fields in $insertFields.
     *
     * @var array
     */
    protected $insertValues = [];
    
    /**
     * Adds a set of field->value pairs to be inserted.
     *
     * This method may only be called once. Calling it a second time will be
     * ignored. To queue up multiple sets of values to be inserted at once,
     * use the values() method.
     *
     * @param array $fields
     *   An array of fields on which to insert. This array may be indexed or
     *   associative. If indexed, the array is taken to be the list of fields.
     *   If associative, the keys of the array are taken to be the fields and
     *   the values are taken to be corresponding values to insert. If a
     *   $values argument is provided, $fields must be indexed.
     * @param array $values
     *   (optional) An array of fields to insert into the database. The values
     *   must be specified in the same order as the $fields array.
     *
     * @return $this
     *   The called object.
     */
    public function fields(array $fields, array $values = []) {
        if (empty($this->insertFields)) {
            if (empty($values)) {
                if (!is_numeric(key($fields))) {
                    $values = array_values($fields);
                    $fields = array_keys($fields);
                }
            }
            $this->insertFields = $fields;
            if (!empty($values)) {
                $this->insertValues[] = $values;
            }
        }
        return $this;
    }
    
    /**
     * Adds another set of values to the query to be inserted.
     *
     * If $values is a numeric-keyed array, it will be assumed to be in the same
     * order as the original fields() call. If it is associative, it may be
     * in any order as long as the keys of the array match the names of the
     * fields.
     *
     * @param array $values
     *   An array of values to add to the query.
     *
     * @return $this
     *   The called object.
     */
    public function values(array $values) {
        if (is_numeric(key($values))) {
            $this->insertValues[] = $values;
        }
        elseif ($this->insertFields) {
            // Reorder the submitted values to match the fields array.
            foreach ($this->insertFields as $key) {
                $insert_values[$key] = $values[$key];
            }
            // For consistency, the values array is always numerically indexed.
            $this->insertValues[] = array_values($insert_values);
        }
        return $this;
    }
    
    /**
     * Specifies fields for which the database defaults should be used.
     *
     * If you want to force a given field to use the database-defined default,
     * not NULL or undefined, use this method to instruct the database to use
     * default values explicitly. In most cases this will not be necessary
     * unless you are inserting a row that is all default values, as you cannot
     * specify no values in an INSERT query.
     *
     * Specifying a field both in fields() and in useDefaults() is an error
     * and will not execute.
     *
     * @param array $fields
     *   An array of values for which to use the default values
     *   specified in the table definition.
     *
     * @return $this
     *   The called object.
     */
    public function useDefaults(array $fields) {
        $this->defaultFields = $fields;
        return $this;
    }
    
    /**
     * Returns the query placeholders for values that will be inserted.
     *
     * @param array $nested_insert_values
     *   A nested array of values to insert.
     * @param array $default_fields
     *   An array of fields that should be set to their database-defined defaults.
     *
     * @return array
     *   An array of insert placeholders.
     */
    protected function getInsertPlaceholderFragment(array $nested_insert_values, array $default_fields) {
        $max_placeholder = 0;
        $values = [];
        if ($nested_insert_values) {
            foreach ($nested_insert_values as $insert_values) {
                $placeholders = [];
                // Default fields aren't really placeholders, but this is the most convenient
                // way to handle them.
                $placeholders = array_pad($placeholders, count($default_fields), 'default');
                $new_placeholder = $max_placeholder + count($insert_values);
                for ($i = $max_placeholder; $i < $new_placeholder; ++$i) {
                    $placeholders[] = ':db_insert_placeholder_' . $i;
                }
                $max_placeholder = $new_placeholder;
                $values[] = '(' . implode(', ', $placeholders) . ')';
            }
        }
        else {
            // If there are no values, then this is a default-only query. We still need to handle that.
            $placeholders = array_fill(0, count($default_fields), 'default');
            $values[] = '(' . implode(', ', $placeholders) . ')';
        }
        return $values;
    }
    
    /**
     * {@inheritdoc}
     */
    public function count() : int {
        return count($this->insertValues);
    }

}

Traits

Title Deprecated Summary
InsertTrait Provides common functionality for INSERT and UPSERT queries.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.