1 | <?php |
---|
2 | |
---|
3 | function date_api_set_variables() { |
---|
4 | // Set absolute minimum and maximum year for dates on this site. |
---|
5 | // There is actually no maximum and minimum year in PHP 5, but a date with |
---|
6 | // a year less than 0 would result in negative ISO and DATETIME dates, |
---|
7 | // like -1250-01-01T00:00:00, which probably won't make sense or work |
---|
8 | // correctly anywhere. |
---|
9 | // |
---|
10 | // The odd construct of using variable_get() instead of variable_set() |
---|
11 | // is so we don't accidentally write over an existing value. If |
---|
12 | // no value is set, variable_get() will set it. |
---|
13 | variable_get('date_max_year', 4000); |
---|
14 | variable_get('date_min_year', 1); |
---|
15 | variable_get('date_php_min_year', 1901); |
---|
16 | |
---|
17 | // Set an API version in a way that other modules can test for compatibility. |
---|
18 | variable_set('date_api_version', '5.2'); |
---|
19 | |
---|
20 | if (version_compare(PHP_VERSION, '5.2', '<') && !module_exists('date_php4')) { |
---|
21 | module_enable(array('date_php4')); |
---|
22 | } |
---|
23 | // The timezone module was originally going to be optional |
---|
24 | // but too many things break without it. |
---|
25 | if (!module_exists('date_timezone')) { |
---|
26 | module_enable(array('date_timezone')); |
---|
27 | } |
---|
28 | |
---|
29 | // NULL is used for the default setting of date_default_timezone_name |
---|
30 | // to have a way to tell that no site timezone name has been implemented. |
---|
31 | // Otherwise, many functions would use 'UTC' incorrectly and |
---|
32 | // produce unreliable and odd results. This way functions can test for a |
---|
33 | // value and not use this if it is empty. |
---|
34 | // |
---|
35 | // The odd construct of using variable_get() instead of variable_set() |
---|
36 | // is so we don't accidentally write over an existing value. If |
---|
37 | // no value is set, variable_get() will set it to NULL. |
---|
38 | variable_get('date_default_timezone_name', NULL); |
---|
39 | } |
---|
40 | |
---|
41 | /** |
---|
42 | * Implementation of hook_schema(). |
---|
43 | */ |
---|
44 | function date_api_schema() { |
---|
45 | $schema['date_format_types'] = array( |
---|
46 | 'description' => 'For storing configured date format types.', |
---|
47 | 'fields' => array( |
---|
48 | 'type' => array( |
---|
49 | 'description' => 'The date format type, e.g. medium.', |
---|
50 | 'type' => 'varchar', |
---|
51 | 'length' => 200, |
---|
52 | 'not null' => TRUE, |
---|
53 | ), |
---|
54 | 'title' => array( |
---|
55 | 'description' => 'The human readable name of the format type.', |
---|
56 | 'type' => 'varchar', |
---|
57 | 'length' => 255, |
---|
58 | 'not null' => TRUE, |
---|
59 | ), |
---|
60 | 'locked' => array( |
---|
61 | 'description' => 'Whether or not this is a system provided format.', |
---|
62 | 'type' => 'int', |
---|
63 | 'size' => 'tiny', |
---|
64 | 'default' => 0, |
---|
65 | 'not null' => TRUE, |
---|
66 | ), |
---|
67 | ), |
---|
68 | 'primary key' => array('type'), |
---|
69 | ); |
---|
70 | |
---|
71 | $schema['date_formats'] = array( |
---|
72 | 'description' => 'For storing configured date formats.', |
---|
73 | 'fields' => array( |
---|
74 | 'dfid' => array( |
---|
75 | 'description' => 'The date format identifier.', |
---|
76 | 'type' => 'serial', |
---|
77 | 'not null' => TRUE, |
---|
78 | 'unsigned' => TRUE, |
---|
79 | ), |
---|
80 | 'format' => array( |
---|
81 | 'description' => 'The date format string.', |
---|
82 | 'type' => 'varchar', |
---|
83 | 'length' => 100, |
---|
84 | 'not null' => TRUE, |
---|
85 | ), |
---|
86 | 'type' => array( |
---|
87 | 'description' => 'The date format type, e.g. medium.', |
---|
88 | 'type' => 'varchar', |
---|
89 | 'length' => 200, |
---|
90 | 'not null' => TRUE, |
---|
91 | ), |
---|
92 | 'locked' => array( |
---|
93 | 'description' => 'Whether or not this format can be modified.', |
---|
94 | 'type' => 'int', |
---|
95 | 'size' => 'tiny', |
---|
96 | 'default' => 0, |
---|
97 | 'not null' => TRUE, |
---|
98 | ), |
---|
99 | ), |
---|
100 | 'primary key' => array('dfid'), |
---|
101 | 'unique keys' => array('formats' => array('format', 'type')), |
---|
102 | ); |
---|
103 | |
---|
104 | $schema['date_format_locale'] = array( |
---|
105 | 'description' => 'For storing configured date formats for each locale.', |
---|
106 | 'fields' => array( |
---|
107 | 'format' => array( |
---|
108 | 'description' => 'The date format string.', |
---|
109 | 'type' => 'varchar', |
---|
110 | 'length' => 100, |
---|
111 | 'not null' => TRUE, |
---|
112 | ), |
---|
113 | 'type' => array( |
---|
114 | 'description' => 'The date format type, e.g. medium.', |
---|
115 | 'type' => 'varchar', |
---|
116 | 'length' => 200, |
---|
117 | 'not null' => TRUE, |
---|
118 | ), |
---|
119 | 'language' => array( |
---|
120 | 'description' => 'A {languages}.language for this format to be used with.', |
---|
121 | 'type' => 'varchar', |
---|
122 | 'length' => 12, |
---|
123 | 'not null' => TRUE, |
---|
124 | ), |
---|
125 | ), |
---|
126 | 'primary key' => array('type', 'language'), |
---|
127 | ); |
---|
128 | |
---|
129 | return $schema; |
---|
130 | } |
---|
131 | |
---|
132 | /** |
---|
133 | * Implementation of hook_schema_alter(). We alter $schema by reference. |
---|
134 | * |
---|
135 | * @param $schema |
---|
136 | * The system-wide schema collected by drupal_get_schema(). |
---|
137 | */ |
---|
138 | function date_api_schema_alter(&$schema) { |
---|
139 | // Add field to existing schema. |
---|
140 | $schema['users']['fields']['timezone_name'] = array( |
---|
141 | 'type' => 'varchar', |
---|
142 | 'length' => 50, |
---|
143 | 'not null' => TRUE, |
---|
144 | 'default' => '', |
---|
145 | 'description' => t('Per-user timezone name.'), |
---|
146 | ); |
---|
147 | } |
---|
148 | |
---|
149 | /** |
---|
150 | * Implementation of hook_install(). |
---|
151 | */ |
---|
152 | function date_api_install() { |
---|
153 | drupal_install_schema('date_api'); |
---|
154 | |
---|
155 | // date_api_set_variables can install date_timezone and date_php4. The |
---|
156 | // date_timezone_install() function does a module_enable('date_api'). This |
---|
157 | // means that date_api_enable() can be called before date_api_install() |
---|
158 | // finishes! So the date_api schema needs to be installed before this line! |
---|
159 | date_api_set_variables(); |
---|
160 | |
---|
161 | $ret = array(); |
---|
162 | db_add_field($ret, "users", "timezone_name", array('type' => 'varchar', 'length' => 50, 'not null' => TRUE, 'default' => '')); |
---|
163 | |
---|
164 | // Make sure MYSQL does not stupidly do case-insensitive |
---|
165 | // searches and indexes on our formats. |
---|
166 | // @see http://pure.rednoize.com/2006/11/26/mysql-collation-matters-when-using-unique-indexes/ |
---|
167 | // @see http://jjinux.blogspot.com/2009/03/mysql-case-sensitivity-hell.html |
---|
168 | // @see http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html |
---|
169 | global $db_type; |
---|
170 | if ($db_type == 'mysql' || $db_type == 'mysqli') { |
---|
171 | $sql = "ALTER TABLE {date_formats} CHANGE format format VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL"; |
---|
172 | $ret[] = update_sql($sql); |
---|
173 | $sql = "ALTER TABLE {date_format_locale} CHANGE format format VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL"; |
---|
174 | $ret[] = update_sql($sql); |
---|
175 | } |
---|
176 | |
---|
177 | return $ret; |
---|
178 | } |
---|
179 | |
---|
180 | /** |
---|
181 | * Implementation of hook_enable(). |
---|
182 | */ |
---|
183 | function date_api_enable() { |
---|
184 | // When module is enabled, build the list of date formats and types. This |
---|
185 | // includes those provided by this module and other contrib modules. As the |
---|
186 | // date_format tables are created but the schema hasn't been updated, force |
---|
187 | // a refresh so we can use the schema API. |
---|
188 | drupal_get_schema('', TRUE); |
---|
189 | // Ensure schema has been installed - order of things gets out of sync because |
---|
190 | // date_api_set_variables() in date_api_install() enables the 'date_timezone' |
---|
191 | // module, which in return enables the 'date_api' module! |
---|
192 | if (db_table_exists('date_format_types')) { |
---|
193 | date_formats_rebuild(); |
---|
194 | } |
---|
195 | date_api_set_variables(); |
---|
196 | |
---|
197 | } |
---|
198 | |
---|
199 | /** |
---|
200 | * Implementation of hook_uninstall(). |
---|
201 | */ |
---|
202 | function date_api_uninstall() { |
---|
203 | $ret = array(); |
---|
204 | db_drop_field($ret, "users", "timezone_name"); |
---|
205 | |
---|
206 | cache_clear_all('date_timezone_identifiers_list', 'cache'); |
---|
207 | $variables = array( |
---|
208 | 'date_api_version', |
---|
209 | 'date_min_year', |
---|
210 | 'date_max_year', |
---|
211 | 'date_php_min_year', |
---|
212 | 'date_db_tz_support', |
---|
213 | 'date_api_use_iso8601', |
---|
214 | ); |
---|
215 | foreach ($variables as $variable) { |
---|
216 | variable_del($variable); |
---|
217 | } |
---|
218 | |
---|
219 | if (db_table_exists('views_display')) { |
---|
220 | $displays = array( |
---|
221 | 'date_nav', |
---|
222 | ); |
---|
223 | db_query("DELETE FROM {views_display} WHERE display_plugin IN ('". implode("','", $displays) ."')"); |
---|
224 | db_query("DELETE FROM {cache_views}"); |
---|
225 | } |
---|
226 | |
---|
227 | drupal_uninstall_schema('date_api'); |
---|
228 | return $ret; |
---|
229 | } |
---|
230 | |
---|
231 | /** |
---|
232 | * Implementation of hook_requirements(). |
---|
233 | * Make sure Date PHP4 is installed if running less than PHP 5.2. |
---|
234 | */ |
---|
235 | function date_api_requirements($phase) { |
---|
236 | $requirements = array(); |
---|
237 | $t = get_t(); |
---|
238 | switch ($phase) { |
---|
239 | case 'runtime': |
---|
240 | $tz_name = variable_get('date_default_timezone_name', NULL); |
---|
241 | $error = FALSE; |
---|
242 | if (version_compare(PHP_VERSION, '5.2', '<') && !module_exists('date_php4')) { |
---|
243 | $error = TRUE; |
---|
244 | $severity = REQUIREMENT_ERROR; |
---|
245 | $value = $t('The Date API module requires the <a href="@link">Date PHP4 module</a> for PHP versions less than 5.2.', array('@link' => url('admin/build/modules'))); |
---|
246 | } |
---|
247 | if ($error) { |
---|
248 | $requirements['date_php4'] = array( |
---|
249 | 'title' => $t('Date API requirements'), |
---|
250 | 'value' => $value, |
---|
251 | 'severity' => $severity, |
---|
252 | ); |
---|
253 | } |
---|
254 | break; |
---|
255 | case 'install': |
---|
256 | break; |
---|
257 | } |
---|
258 | return $requirements; |
---|
259 | } |
---|
260 | |
---|
261 | function date_api_update_last_removed() { |
---|
262 | return 5201; |
---|
263 | } |
---|
264 | |
---|
265 | /** |
---|
266 | * Make sure all the appropriate modules get enabled. |
---|
267 | * Repeated again just to be sure they are set. |
---|
268 | */ |
---|
269 | function date_api_update_6000() { |
---|
270 | $ret = array(); |
---|
271 | // don't attempt to upgrade if views is not yet upgraded. |
---|
272 | if (module_exists('views') && drupal_get_installed_schema_version('views', TRUE) < 6000) { |
---|
273 | $ret = array(); |
---|
274 | drupal_set_message(t('date module cannot be updated until after Views has been updated. Please return to <a href="@update-php">update.php</a> and run the remaining updates.', array('@update-php' => base_path() .'update.php?op=selection')), 'warning', FALSE); |
---|
275 | $ret['#abort'] = array('success' => FALSE, 'query' => t('date.module has updates, but cannot be updated until views.module is updated first.')); |
---|
276 | |
---|
277 | return $ret; |
---|
278 | } |
---|
279 | date_api_set_variables(); |
---|
280 | return $ret; |
---|
281 | } |
---|
282 | |
---|
283 | /** |
---|
284 | * Rebuild the theme registry and all the caches. |
---|
285 | * needed to pick up changes created by updated Views API. |
---|
286 | */ |
---|
287 | function date_api_update_6001() { |
---|
288 | $ret = array(); |
---|
289 | // don't attempt to upgrade if views is not yet upgraded. |
---|
290 | if (module_exists('views') && drupal_get_installed_schema_version('views', TRUE) < 6000) { |
---|
291 | $ret = array(); |
---|
292 | drupal_set_message(t('date module cannot be updated until after Views has been updated. Please return to <a href="@update-php">update.php</a> and run the remaining updates.', array('@update-php' => base_path() .'update.php?op=selection')), 'warning', FALSE); |
---|
293 | $ret['#abort'] = array('success' => FALSE, 'query' => t('date.module has updates, but cannot be updated until views.module is updated first.')); |
---|
294 | |
---|
295 | return $ret; |
---|
296 | } |
---|
297 | if (db_table_exists('cache_content')) { |
---|
298 | db_query('DELETE FROM {cache_content}'); |
---|
299 | } |
---|
300 | if (db_table_exists('cache_views')) { |
---|
301 | db_query('DELETE FROM {cache_views}'); |
---|
302 | } |
---|
303 | if (db_table_exists('views_object_cache')) { |
---|
304 | db_query('DELETE FROM {views_object_cache}'); |
---|
305 | } |
---|
306 | db_query("DELETE FROM {cache} where cid LIKE 'theme_registry%'"); |
---|
307 | return $ret; |
---|
308 | } |
---|
309 | |
---|
310 | /** |
---|
311 | * Create new date format tables. |
---|
312 | */ |
---|
313 | function date_api_update_6002() { |
---|
314 | $ret = array(); |
---|
315 | // don't attempt to upgrade if views is not yet upgraded. |
---|
316 | if (module_exists('views') && drupal_get_installed_schema_version('views', TRUE) < 6000) { |
---|
317 | $ret = array(); |
---|
318 | drupal_set_message(t('date module cannot be updated until after Views has been updated. Please return to <a href="@update-php">update.php</a> and run the remaining updates.', array('@update-php' => base_path() .'update.php?op=selection')), 'warning', FALSE); |
---|
319 | $ret['#abort'] = array('success' => FALSE, 'query' => t('date.module has updates, but cannot be updated until views.module is updated first.')); |
---|
320 | |
---|
321 | return $ret; |
---|
322 | } |
---|
323 | |
---|
324 | $schema['date_format_types'] = array( |
---|
325 | 'fields' => array( |
---|
326 | 'type' => array( |
---|
327 | 'type' => 'varchar', |
---|
328 | 'length' => 200, |
---|
329 | 'not null' => TRUE, |
---|
330 | ), |
---|
331 | 'title' => array( |
---|
332 | 'type' => 'varchar', |
---|
333 | 'length' => 255, |
---|
334 | 'not null' => TRUE, |
---|
335 | ), |
---|
336 | 'locked' => array( |
---|
337 | 'type' => 'int', |
---|
338 | 'size' => 'tiny', |
---|
339 | 'default' => 0, |
---|
340 | 'not null' => TRUE, |
---|
341 | ), |
---|
342 | ), |
---|
343 | 'primary key' => array('type'), |
---|
344 | ); |
---|
345 | |
---|
346 | $schema['date_format'] = array( |
---|
347 | 'fields' => array( |
---|
348 | 'dfid' => array( |
---|
349 | 'type' => 'serial', |
---|
350 | 'not null' => TRUE, |
---|
351 | 'unsigned' => TRUE, |
---|
352 | ), |
---|
353 | 'format' => array( |
---|
354 | 'type' => 'varchar', |
---|
355 | 'length' => 100, |
---|
356 | 'not null' => TRUE, |
---|
357 | ), |
---|
358 | 'type' => array( |
---|
359 | 'type' => 'varchar', |
---|
360 | 'length' => 200, |
---|
361 | 'not null' => TRUE, |
---|
362 | ), |
---|
363 | 'locked' => array( |
---|
364 | 'type' => 'int', |
---|
365 | 'size' => 'tiny', |
---|
366 | 'default' => 0, |
---|
367 | 'not null' => TRUE, |
---|
368 | ), |
---|
369 | ), |
---|
370 | 'primary key' => array('dfid'), |
---|
371 | 'unique keys' => array('format' => array('format', 'type')), |
---|
372 | ); |
---|
373 | |
---|
374 | $schema['date_format_locale'] = array( |
---|
375 | 'fields' => array( |
---|
376 | 'format' => array( |
---|
377 | 'type' => 'varchar', |
---|
378 | 'length' => 255, |
---|
379 | 'not null' => TRUE, |
---|
380 | ), |
---|
381 | 'type' => array( |
---|
382 | 'type' => 'varchar', |
---|
383 | 'length' => 200, |
---|
384 | 'not null' => TRUE, |
---|
385 | ), |
---|
386 | 'language' => array( |
---|
387 | 'type' => 'varchar', |
---|
388 | 'length' => 12, |
---|
389 | 'not null' => TRUE, |
---|
390 | ), |
---|
391 | ), |
---|
392 | 'primary key' => array('type', 'language'), |
---|
393 | ); |
---|
394 | |
---|
395 | db_create_table($ret, 'date_format_types', $schema['date_format_types']); |
---|
396 | db_create_table($ret, 'date_format', $schema['date_format']); |
---|
397 | db_create_table($ret, 'date_format_locale', $schema['date_format_locale']); |
---|
398 | |
---|
399 | return $ret; |
---|
400 | } |
---|
401 | |
---|
402 | function date_api_update_6003() { |
---|
403 | $ret = array(); |
---|
404 | db_change_field($ret, 'date_format_types', 'type', 'type', array('type' => 'varchar', 'length' => 200, 'not null' => TRUE)); |
---|
405 | db_change_field($ret, 'date_format', 'type', 'type', array('type' => 'varchar', 'length' => 200, 'not null' => TRUE)); |
---|
406 | db_change_field($ret, 'date_format', 'format', 'format', array('type' => 'varchar', 'length' => 100, 'not null' => TRUE)); |
---|
407 | db_change_field($ret, 'date_format_locale', 'type', 'type', array('type' => 'varchar', 'length' => 200, 'not null' => TRUE)); |
---|
408 | db_change_field($ret, 'date_format_locale', 'format', 'format', array('type' => 'varchar', 'length' => 100, 'not null' => TRUE)); |
---|
409 | db_drop_unique_key($ret, 'date_format', 'format'); |
---|
410 | db_add_unique_key($ret, 'date_format', 'format', array('format', 'type')); |
---|
411 | return $ret; |
---|
412 | } |
---|
413 | |
---|
414 | /** |
---|
415 | * The "date_format" table is missing on boxes having MySQL 5.0.67 installed. |
---|
416 | * There seems to be a bug in MySQL that prevents the creation of tables with |
---|
417 | * a name "date_format" and indexes with the name "format". |
---|
418 | * |
---|
419 | * We rename the table and index as a workaround. |
---|
420 | */ |
---|
421 | function date_api_update_6004() { |
---|
422 | $ret = array(); |
---|
423 | |
---|
424 | $schema['date_formats'] = array( |
---|
425 | 'description' => 'For storing configured date formats.', |
---|
426 | 'fields' => array( |
---|
427 | 'dfid' => array( |
---|
428 | 'description' => 'The date format identifier.', |
---|
429 | 'type' => 'serial', |
---|
430 | 'not null' => TRUE, |
---|
431 | 'unsigned' => TRUE, |
---|
432 | ), |
---|
433 | 'format' => array( |
---|
434 | 'description' => 'The date format string.', |
---|
435 | 'type' => 'varchar', |
---|
436 | 'length' => 100, |
---|
437 | 'not null' => TRUE, |
---|
438 | ), |
---|
439 | 'type' => array( |
---|
440 | 'description' => 'The date format type, e.g. medium.', |
---|
441 | 'type' => 'varchar', |
---|
442 | 'length' => 200, |
---|
443 | 'not null' => TRUE, |
---|
444 | ), |
---|
445 | 'locked' => array( |
---|
446 | 'description' => 'Whether or not this format can be modified.', |
---|
447 | 'type' => 'int', |
---|
448 | 'size' => 'tiny', |
---|
449 | 'default' => 0, |
---|
450 | 'not null' => TRUE, |
---|
451 | ), |
---|
452 | ), |
---|
453 | 'primary key' => array('dfid'), |
---|
454 | 'unique keys' => array('formats' => array('format', 'type')), |
---|
455 | ); |
---|
456 | |
---|
457 | // Create missing table. |
---|
458 | if (!db_table_exists('date_format')) { |
---|
459 | db_create_table($ret, 'date_formats', $schema['date_formats']); |
---|
460 | date_formats_rebuild(); |
---|
461 | } |
---|
462 | // Rename existing table and index. |
---|
463 | else { |
---|
464 | db_drop_unique_key($ret, 'date_format', 'format'); |
---|
465 | if (db_table_exists('date_formats')) { |
---|
466 | db_drop_table($ret, 'date_format'); |
---|
467 | } |
---|
468 | else { |
---|
469 | db_rename_table($ret, 'date_format', 'date_formats'); |
---|
470 | db_add_unique_key($ret, 'date_formats', 'formats', array('format', 'type')); |
---|
471 | } |
---|
472 | } |
---|
473 | |
---|
474 | return $ret; |
---|
475 | } |
---|
476 | |
---|
477 | /** |
---|
478 | * Make sure MYSQL does not stupidly do case-insensitive |
---|
479 | * searches and indexes on our formats. |
---|
480 | * @see http://pure.rednoize.com/2006/11/26/mysql-collation-matters-when-using-unique-indexes/ |
---|
481 | * @see http://jjinux.blogspot.com/2009/03/mysql-case-sensitivity-hell.html |
---|
482 | * @see http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html |
---|
483 | */ |
---|
484 | function date_api_update_6005() { |
---|
485 | global $db_type; |
---|
486 | $ret = array(); |
---|
487 | if ($db_type == 'mysql' || $db_type == 'mysqli') { |
---|
488 | $sql = "ALTER TABLE {date_formats} CHANGE format format VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL"; |
---|
489 | $ret[] = update_sql($sql); |
---|
490 | $sql = "ALTER TABLE {date_format_locale} CHANGE format format VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL"; |
---|
491 | $ret[] = update_sql($sql); |
---|
492 | } |
---|
493 | return $ret; |
---|
494 | } |
---|
495 | |
---|
496 | /** |
---|
497 | * Rename the date_format_dfid_seq to date_formats_dfid_seq, as this was missed in 6004 |
---|
498 | * and causes inserts via the UI to fail on PostgreSQL. |
---|
499 | */ |
---|
500 | function date_api_update_6006() { |
---|
501 | global $db_type; |
---|
502 | $ret = array(); |
---|
503 | if ($db_type == 'pgsql' && db_table_exists('date_format_dfid_seq')) { |
---|
504 | $sql = "ALTER TABLE {date_format}_dfid_seq RENAME TO {date_formats}_dfid_seq"; |
---|
505 | $ret[] = update_sql($sql); |
---|
506 | } |
---|
507 | return $ret; |
---|
508 | } |
---|