Upgraded drupal core with security updates
[yaffs-website] / web / core / lib / Drupal / Core / Database / Query / InsertTrait.php
1 <?php
2
3 namespace Drupal\Core\Database\Query;
4
5 /**
6  * Provides common functionality for INSERT and UPSERT queries.
7  *
8  * @ingroup database
9  */
10 trait InsertTrait {
11
12   /**
13    * The table on which to insert.
14    *
15    * @var string
16    */
17   protected $table;
18
19   /**
20    * An array of fields on which to insert.
21    *
22    * @var array
23    */
24   protected $insertFields = [];
25
26   /**
27    * An array of fields that should be set to their database-defined defaults.
28    *
29    * @var array
30    */
31   protected $defaultFields = [];
32
33   /**
34    * A nested array of values to insert.
35    *
36    * $insertValues is an array of arrays. Each sub-array is either an
37    * associative array whose keys are field names and whose values are field
38    * values to insert, or a non-associative array of values in the same order
39    * as $insertFields.
40    *
41    * Whether multiple insert sets will be run in a single query or multiple
42    * queries is left to individual drivers to implement in whatever manner is
43    * most appropriate. The order of values in each sub-array must match the
44    * order of fields in $insertFields.
45    *
46    * @var array
47    */
48   protected $insertValues = [];
49
50   /**
51    * Adds a set of field->value pairs to be inserted.
52    *
53    * This method may only be called once. Calling it a second time will be
54    * ignored. To queue up multiple sets of values to be inserted at once,
55    * use the values() method.
56    *
57    * @param array $fields
58    *   An array of fields on which to insert. This array may be indexed or
59    *   associative. If indexed, the array is taken to be the list of fields.
60    *   If associative, the keys of the array are taken to be the fields and
61    *   the values are taken to be corresponding values to insert. If a
62    *   $values argument is provided, $fields must be indexed.
63    * @param array $values
64    *   (optional) An array of fields to insert into the database. The values
65    *   must be specified in the same order as the $fields array.
66    *
67    * @return $this
68    *   The called object.
69    */
70   public function fields(array $fields, array $values = []) {
71     if (empty($this->insertFields)) {
72       if (empty($values)) {
73         if (!is_numeric(key($fields))) {
74           $values = array_values($fields);
75           $fields = array_keys($fields);
76         }
77       }
78       $this->insertFields = $fields;
79       if (!empty($values)) {
80         $this->insertValues[] = $values;
81       }
82     }
83
84     return $this;
85   }
86
87   /**
88    * Adds another set of values to the query to be inserted.
89    *
90    * If $values is a numeric-keyed array, it will be assumed to be in the same
91    * order as the original fields() call. If it is associative, it may be
92    * in any order as long as the keys of the array match the names of the
93    * fields.
94    *
95    * @param array $values
96    *   An array of values to add to the query.
97    *
98    * @return $this
99    *   The called object.
100    */
101   public function values(array $values) {
102     if (is_numeric(key($values))) {
103       $this->insertValues[] = $values;
104     }
105     elseif ($this->insertFields) {
106       // Reorder the submitted values to match the fields array.
107       foreach ($this->insertFields as $key) {
108         $insert_values[$key] = $values[$key];
109       }
110       // For consistency, the values array is always numerically indexed.
111       $this->insertValues[] = array_values($insert_values);
112     }
113     return $this;
114   }
115
116   /**
117    * Specifies fields for which the database defaults should be used.
118    *
119    * If you want to force a given field to use the database-defined default,
120    * not NULL or undefined, use this method to instruct the database to use
121    * default values explicitly. In most cases this will not be necessary
122    * unless you are inserting a row that is all default values, as you cannot
123    * specify no values in an INSERT query.
124    *
125    * Specifying a field both in fields() and in useDefaults() is an error
126    * and will not execute.
127    *
128    * @param array $fields
129    *   An array of values for which to use the default values
130    *   specified in the table definition.
131    *
132    * @return $this
133    *   The called object.
134    */
135   public function useDefaults(array $fields) {
136     $this->defaultFields = $fields;
137     return $this;
138   }
139
140   /**
141    * Returns the query placeholders for values that will be inserted.
142    *
143    * @param array $nested_insert_values
144    *   A nested array of values to insert.
145    * @param array $default_fields
146    *   An array of fields that should be set to their database-defined defaults.
147    *
148    * @return array
149    *   An array of insert placeholders.
150    */
151   protected function getInsertPlaceholderFragment(array $nested_insert_values, array $default_fields) {
152     $max_placeholder = 0;
153     $values = [];
154     if ($nested_insert_values) {
155       foreach ($nested_insert_values as $insert_values) {
156         $placeholders = [];
157
158         // Default fields aren't really placeholders, but this is the most convenient
159         // way to handle them.
160         $placeholders = array_pad($placeholders, count($default_fields), 'default');
161
162         $new_placeholder = $max_placeholder + count($insert_values);
163         for ($i = $max_placeholder; $i < $new_placeholder; ++$i) {
164           $placeholders[] = ':db_insert_placeholder_' . $i;
165         }
166         $max_placeholder = $new_placeholder;
167         $values[] = '(' . implode(', ', $placeholders) . ')';
168       }
169     }
170     else {
171       // If there are no values, then this is a default-only query. We still need to handle that.
172       $placeholders = array_fill(0, count($default_fields), 'default');
173       $values[] = '(' . implode(', ', $placeholders) . ')';
174     }
175
176     return $values;
177   }
178
179   /**
180    * {@inheritdoc}
181    */
182   public function count() {
183     return count($this->insertValues);
184   }
185
186 }