Upgraded drupal core with security updates
[yaffs-website] / web / core / includes / schema.inc
1 <?php
2
3 /**
4  * @file
5  * Schema API handling functions.
6  */
7
8 /**
9  * @addtogroup schemaapi
10  * @{
11  */
12
13 /**
14  * Indicates that a module has not been installed yet.
15  */
16 const SCHEMA_UNINSTALLED = -1;
17
18 /**
19  * Returns an array of available schema versions for a module.
20  *
21  * @param string $module
22  *   A module name.
23  *
24  * @return array|bool
25  *   If the module has updates, an array of available updates sorted by
26  *   version. Otherwise, FALSE.
27  */
28 function drupal_get_schema_versions($module) {
29   $updates = &drupal_static(__FUNCTION__, NULL);
30   if (!isset($updates[$module])) {
31     $updates = [];
32     foreach (\Drupal::moduleHandler()->getModuleList() as $loaded_module => $filename) {
33       $updates[$loaded_module] = [];
34     }
35
36     // Prepare regular expression to match all possible defined hook_update_N().
37     $regexp = '/^(?<module>.+)_update_(?<version>\d+)$/';
38     $functions = get_defined_functions();
39     // Narrow this down to functions ending with an integer, since all
40     // hook_update_N() functions end this way, and there are other
41     // possible functions which match '_update_'. We use preg_grep() here
42     // instead of foreaching through all defined functions, since the loop
43     // through all PHP functions can take significant page execution time
44     // and this function is called on every administrative page via
45     // system_requirements().
46     foreach (preg_grep('/_\d+$/', $functions['user']) as $function) {
47       // If this function is a module update function, add it to the list of
48       // module updates.
49       if (preg_match($regexp, $function, $matches)) {
50         $updates[$matches['module']][] = $matches['version'];
51       }
52     }
53     // Ensure that updates are applied in numerical order.
54     foreach ($updates as &$module_updates) {
55       sort($module_updates, SORT_NUMERIC);
56     }
57   }
58   return empty($updates[$module]) ? FALSE : $updates[$module];
59 }
60
61 /**
62  * Returns the currently installed schema version for a module.
63  *
64  * @param string $module
65  *   A module name.
66  * @param bool $reset
67  *   Set to TRUE after installing or uninstalling an extension.
68  * @param bool $array
69  *   Set to TRUE if you want to get information about all modules in the
70  *   system.
71  *
72  * @return string|int
73  *   The currently installed schema version, or SCHEMA_UNINSTALLED if the
74  *   module is not installed.
75  */
76 function drupal_get_installed_schema_version($module, $reset = FALSE, $array = FALSE) {
77   $versions = &drupal_static(__FUNCTION__, []);
78
79   if ($reset) {
80     $versions = [];
81   }
82
83   if (!$versions) {
84     if (!$versions = \Drupal::keyValue('system.schema')->getAll()) {
85       $versions = [];
86     }
87   }
88
89   if ($array) {
90     return $versions;
91   }
92   else {
93     return isset($versions[$module]) ? $versions[$module] : SCHEMA_UNINSTALLED;
94   }
95 }
96
97 /**
98  * Updates the installed version information for a module.
99  *
100  * @param string $module
101  *   A module name.
102  * @param string $version
103  *   The new schema version.
104  */
105 function drupal_set_installed_schema_version($module, $version) {
106   \Drupal::keyValue('system.schema')->set($module, $version);
107   // Reset the static cache of module schema versions.
108   drupal_get_installed_schema_version(NULL, TRUE);
109 }
110
111 /**
112  * Creates all tables defined in a module's hook_schema().
113  *
114  * @param string $module
115  *   The module for which the tables will be created.
116  */
117 function drupal_install_schema($module) {
118   $schema = drupal_get_module_schema($module);
119   _drupal_schema_initialize($schema, $module, FALSE);
120
121   foreach ($schema as $name => $table) {
122     db_create_table($name, $table);
123   }
124 }
125
126 /**
127  * Removes all tables defined in a module's hook_schema().
128  *
129  * @param string $module
130  *   The module for which the tables will be removed.
131  */
132 function drupal_uninstall_schema($module) {
133   $schema = drupal_get_module_schema($module);
134   _drupal_schema_initialize($schema, $module, FALSE);
135
136   foreach ($schema as $table) {
137     if (db_table_exists($table['name'])) {
138       db_drop_table($table['name']);
139     }
140   }
141 }
142
143 /**
144  * Returns a module's schema.
145  *
146  * This function can be used to retrieve a schema specification in
147  * hook_schema(), so it allows you to derive your tables from existing
148  * specifications.
149  *
150  * @param string $module
151  *   The module to which the table belongs.
152  * @param string $table
153  *   The name of the table. If not given, the module's complete schema
154  *   is returned.
155  */
156 function drupal_get_module_schema($module, $table = NULL) {
157   // Load the .install file to get hook_schema.
158   module_load_install($module);
159   $schema = \Drupal::moduleHandler()->invoke($module, 'schema');
160
161   if (isset($table)) {
162     if (isset($schema[$table])) {
163       return $schema[$table];
164     }
165     return [];
166   }
167   elseif (!empty($schema)) {
168     return $schema;
169   }
170   return [];
171 }
172
173 /**
174  * Fills in required default values for table definitions from hook_schema().
175  *
176  * @param array $schema
177  *   The schema definition array as it was returned by the module's
178  *   hook_schema().
179  * @param string $module
180  *   The module for which hook_schema() was invoked.
181  * @param bool $remove_descriptions
182  *   (optional) Whether to additionally remove 'description' keys of all tables
183  *   and fields to improve performance of serialize() and unserialize().
184  *   Defaults to TRUE.
185  */
186 function _drupal_schema_initialize(&$schema, $module, $remove_descriptions = TRUE) {
187   // Set the name and module key for all tables.
188   foreach ($schema as $name => &$table) {
189     if (empty($table['module'])) {
190       $table['module'] = $module;
191     }
192     if (!isset($table['name'])) {
193       $table['name'] = $name;
194     }
195     if ($remove_descriptions) {
196       unset($table['description']);
197       foreach ($table['fields'] as &$field) {
198         unset($field['description']);
199       }
200     }
201   }
202 }
203
204 /**
205  * Typecasts values to proper datatypes.
206  *
207  * MySQL PDO silently casts, e.g. FALSE and '' to 0, when inserting the value
208  * into an integer column, but PostgreSQL PDO does not. Look up the schema
209  * information and use that to correctly typecast the value.
210  *
211  * @param array $info
212  *   An array describing the schema field info.
213  * @param mixed $value
214  *   The value to be converted.
215  *
216  * @return mixed
217  *   The converted value.
218  */
219 function drupal_schema_get_field_value(array $info, $value) {
220   // Preserve legal NULL values.
221   if (isset($value) || !empty($info['not null'])) {
222     if ($info['type'] == 'int' || $info['type'] == 'serial') {
223       $value = (int) $value;
224     }
225     elseif ($info['type'] == 'float') {
226       $value = (float) $value;
227     }
228     elseif (!is_array($value)) {
229       $value = (string) $value;
230     }
231   }
232   return $value;
233 }
234
235 /**
236  * @} End of "addtogroup schemaapi".
237  */