| 1 |
<?php
|
| 2 |
// $Id: demo.admin.inc,v 1.20 2009/07/29 14:01:32 sun Exp $
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* Demonstration Site administrative pages
|
| 7 |
*/
|
| 8 |
|
| 9 |
/**
|
| 10 |
* Current version of SQL dump structure.
|
| 11 |
*/
|
| 12 |
define('DEMO_DUMP_VERSION', '1.1');
|
| 13 |
|
| 14 |
function demo_admin_settings($form, &$form_state) {
|
| 15 |
global $base_url;
|
| 16 |
|
| 17 |
$form['status'] = array(
|
| 18 |
'#type' => 'fieldset',
|
| 19 |
'#title' => t('Status'),
|
| 20 |
'#collapsible' => FALSE,
|
| 21 |
);
|
| 22 |
if (variable_get('demo_reset_last', 0)) {
|
| 23 |
$reset_date = format_date(variable_get('demo_reset_last', 0));
|
| 24 |
}
|
| 25 |
else {
|
| 26 |
$reset_date = t('Never');
|
| 27 |
}
|
| 28 |
$form['status'][] = array(
|
| 29 |
'#markup' => t('<p><strong>Last reset:</strong> !date</p>', array('!date' => $reset_date)),
|
| 30 |
);
|
| 31 |
$form['status'][] = array(
|
| 32 |
'#markup' => t('<p><strong>Default snapshot:</strong> !snapshot</p>', array('!snapshot' => variable_get('demo_dump_cron', t('None')))),
|
| 33 |
);
|
| 34 |
|
| 35 |
$fileconfig = demo_get_fileconfig();
|
| 36 |
|
| 37 |
$form['dump'] = array(
|
| 38 |
'#type' => 'fieldset',
|
| 39 |
'#title' => t('Dump settings'),
|
| 40 |
'#collapsible' => TRUE,
|
| 41 |
'#collapsed' => (variable_get('demo_reset_interval', 0) ? FALSE : TRUE),
|
| 42 |
);
|
| 43 |
$period = drupal_map_assoc(array(0, 1800, 3600, 7200, 10800, 14400, 18000, 21600, 32400, 43200, 86400, 172800, 259200, 604800, 1209600, 2419200, 4838400, 9676800), 'format_interval');
|
| 44 |
$period[0] = t('disabled');
|
| 45 |
$form['dump']['interval'] = array(
|
| 46 |
'#type' => 'select',
|
| 47 |
'#title' => t('Automatically reset site every'),
|
| 48 |
'#default_value' => variable_get('demo_reset_interval', 0),
|
| 49 |
'#options' => $period,
|
| 50 |
'#description' => t('Select how often this demonstration site is automatically reset. Ensure that you have chosen a snapshot for cron runs in <a href="!manage">Manage snapshots</a> first. <strong>Note:</strong> This requires cron to run at least within this interval.', array('!manage' => url('admin/structure/demo/manage'))),
|
| 51 |
);
|
| 52 |
|
| 53 |
$form['dump']['path'] = array(
|
| 54 |
'#type' => 'textfield',
|
| 55 |
'#title' => t('Dump path'),
|
| 56 |
'#default_value' => $fileconfig['path'],
|
| 57 |
'#size' => 30,
|
| 58 |
'#description' => t('Enter a writable directory where dump files of this demonstration site are stored, f.e. %files. The name of this site (e.g. %confpath) is automatically appended to this directory, if required.<br /><br /><strong>Note: For security reasons you should store site dumps outside of the document root of your webspace!</strong>', array('%files' => file_directory_path() . '/demo', '%confpath' => $fileconfig['site'])),
|
| 59 |
);
|
| 60 |
$form[] = array(
|
| 61 |
'#type' => 'submit',
|
| 62 |
'#value' => t('Save'),
|
| 63 |
);
|
| 64 |
|
| 65 |
return $form;
|
| 66 |
}
|
| 67 |
|
| 68 |
function demo_admin_settings_submit($form, &$form_state) {
|
| 69 |
if (!file_check_directory($form_state['values']['path'], FILE_CREATE_DIRECTORY)) {
|
| 70 |
form_set_error('path', t('The snapshot directory %directory could not be created.', array('%directory' => $form_state['values']['path'])));
|
| 71 |
return FALSE;
|
| 72 |
}
|
| 73 |
else {
|
| 74 |
variable_set('demo_dump_path', $form_state['values']['path']);
|
| 75 |
}
|
| 76 |
variable_set('demo_reset_interval', $form_state['values']['interval']);
|
| 77 |
drupal_set_message(t('The configuration options have been saved.'));
|
| 78 |
}
|
| 79 |
|
| 80 |
function demo_manage($form, &$form_state) {
|
| 81 |
$form['dump'] = array(
|
| 82 |
'#type' => 'fieldset',
|
| 83 |
'#title' => t('Available snapshots'),
|
| 84 |
);
|
| 85 |
$form = array_merge_recursive($form, demo_get_dumps());
|
| 86 |
$form[] = array(
|
| 87 |
'#type' => 'submit',
|
| 88 |
'#value' => t('Use for cron runs'),
|
| 89 |
);
|
| 90 |
$form[] = array(
|
| 91 |
'#type' => 'submit',
|
| 92 |
'#value' => t('Delete'),
|
| 93 |
'#submit' => array('demo_manage_delete_submit'),
|
| 94 |
);
|
| 95 |
return $form;
|
| 96 |
}
|
| 97 |
|
| 98 |
function demo_manage_submit($form, &$form_state) {
|
| 99 |
demo_set_default($form_state['values']['filename']);
|
| 100 |
}
|
| 101 |
|
| 102 |
function demo_manage_delete_submit($form, &$form_state) {
|
| 103 |
$form_state['redirect'] = 'admin/structure/demo/delete/' . $form_state['values']['filename'];
|
| 104 |
}
|
| 105 |
|
| 106 |
function demo_delete_confirm($form, &$form_state, $filename) {
|
| 107 |
$fileconfig = demo_get_fileconfig($filename);
|
| 108 |
if (!file_exists($fileconfig['infofile'])) {
|
| 109 |
return drupal_access_denied();
|
| 110 |
}
|
| 111 |
|
| 112 |
$form['filename'] = array(
|
| 113 |
'#type' => 'value',
|
| 114 |
'#value' => $filename,
|
| 115 |
);
|
| 116 |
return confirm_form($form, t('Are you sure you want to delete the snapshot %title?', array('%title' => $filename)), 'admin/structure/demo/manage', t('This action cannot be undone.'), t('Delete'));
|
| 117 |
}
|
| 118 |
|
| 119 |
function demo_delete_confirm_submit($form, &$form_state) {
|
| 120 |
$files = demo_get_fileconfig($form_state['values']['filename']);
|
| 121 |
unlink($files['sqlfile']);
|
| 122 |
unlink($files['infofile']);
|
| 123 |
drupal_set_message(t('Snapshot %title has been deleted.', array('%title' => $form_state['values']['filename'])));
|
| 124 |
$form_state['redirect'] = 'admin/structure/demo/manage';
|
| 125 |
}
|
| 126 |
|
| 127 |
function demo_dump($form, &$form_state) {
|
| 128 |
$form['dump']['filename'] = array(
|
| 129 |
'#title' => t('File name'),
|
| 130 |
'#type' => 'textfield',
|
| 131 |
'#autocomplete_path' => 'demo/autocomplete',
|
| 132 |
'#required' => TRUE,
|
| 133 |
'#maxlength' => 128,
|
| 134 |
'#description' => t('Enter the snapshot file name without file extension. Allowed characters are a-z, 0-9, dashes ("-"), underscores ("_") and dots.'),
|
| 135 |
);
|
| 136 |
$form['dump']['default'] = array(
|
| 137 |
'#title' => t('Set as new default snapshot'),
|
| 138 |
'#type' => 'checkbox',
|
| 139 |
);
|
| 140 |
$form['dump']['description'] = array(
|
| 141 |
'#title' => t('Description'),
|
| 142 |
'#type' => 'textarea',
|
| 143 |
'#rows' => 2,
|
| 144 |
'#description' => t('Optionally enter a description for this snapshot here. If no description is given and a snapshot with the same filename already exists, the previous description is used.'),
|
| 145 |
);
|
| 146 |
return confirm_form($form, t('Are you sure you want to create a new snapshot?'), 'admin/structure/demo', t('If the above filename already exists, creating a new snapshot will overwrite the existing snapshot. This action cannot be undone.'), t('Create'), t('Cancel'));
|
| 147 |
}
|
| 148 |
|
| 149 |
function demo_dump_submit($form, &$form_state) {
|
| 150 |
// Generate info file.
|
| 151 |
$info = demo_set_info($form_state['values']);
|
| 152 |
if (!$info) {
|
| 153 |
return FALSE;
|
| 154 |
}
|
| 155 |
|
| 156 |
// Include database specific functions.
|
| 157 |
$engine = db_driver();
|
| 158 |
$inc_file = drupal_get_path('module', 'demo') . '/database_' . $engine . '_dump.inc';
|
| 159 |
if (file_exists($inc_file)) {
|
| 160 |
require_once $inc_file;
|
| 161 |
|
| 162 |
if (!empty($form_state['values']['default'])) {
|
| 163 |
// Set new default snapshot.
|
| 164 |
demo_set_default($info['filename']);
|
| 165 |
}
|
| 166 |
|
| 167 |
// Increase PHP's max_execution_time for large dumps.
|
| 168 |
@set_time_limit(600);
|
| 169 |
|
| 170 |
// Perform dump.
|
| 171 |
$fileconfig = demo_get_fileconfig($info['filename']);
|
| 172 |
$exclude = array(
|
| 173 |
'{cache}',
|
| 174 |
'{cache_admin_menu}',
|
| 175 |
'{cache_block}',
|
| 176 |
'{cache_content}',
|
| 177 |
'{cache_filter}',
|
| 178 |
'{cache_form}',
|
| 179 |
'{cache_menu}',
|
| 180 |
'{cache_page}',
|
| 181 |
'{cache_path}',
|
| 182 |
'{cache_registry}',
|
| 183 |
'{cache_views}',
|
| 184 |
'{ctools_object_cache}',
|
| 185 |
'{panels_object_cache}',
|
| 186 |
'{views_object_cache}',
|
| 187 |
'{watchdog}',
|
| 188 |
);
|
| 189 |
$exclude = array_map(array('DatabaseConnection', 'prefixTables'), $exclude);
|
| 190 |
demo_dump_db($fileconfig['sqlfile'], $exclude);
|
| 191 |
drupal_set_message(t('Successfully created snapshot %filename.', array('%filename' => $fileconfig['sqlfile'])));
|
| 192 |
}
|
| 193 |
else {
|
| 194 |
drupal_set_message(t('@engine support not implemented yet.', array('@engine' => ucfirst($engine))), 'error');
|
| 195 |
}
|
| 196 |
|
| 197 |
$form_state['redirect'] = 'admin/structure/demo/manage';
|
| 198 |
}
|
| 199 |
|
| 200 |
function demo_reset_confirm($form, &$form_state) {
|
| 201 |
$form['dump'] = array(
|
| 202 |
'#type' => 'fieldset',
|
| 203 |
'#title' => t('Available snapshots'),
|
| 204 |
);
|
| 205 |
$form = array_merge_recursive($form, demo_get_dumps());
|
| 206 |
|
| 207 |
return confirm_form($form, t('Are you sure you want to reset the site?'), 'admin/structure/demo', t('Resetting the site will overwrite all changes that have been made to this Drupal installation since the chosen snapshot.<br /><br /><div style="color: red; font-weight: bold; font-size: 18px;"><center>THIS ACTION CANNOT BE UNDONE!</center><br /></div>'), t('Reset'), t('Cancel'));
|
| 208 |
}
|
| 209 |
|
| 210 |
function demo_reset_confirm_submit($form, &$form_state) {
|
| 211 |
// Increase PHP's max_execution_time for large dumps.
|
| 212 |
@set_time_limit(600);
|
| 213 |
|
| 214 |
// Reset site to chosen snapshot.
|
| 215 |
demo_reset($form_state['values']['filename']);
|
| 216 |
// Save time of last reset.
|
| 217 |
variable_set('demo_reset_last', REQUEST_TIME);
|
| 218 |
|
| 219 |
$form_state['redirect'] = isset($form_state['values']['redirect']) ? $form_state['values']['redirect'] : 'admin/structure/demo';
|
| 220 |
}
|
| 221 |
|
| 222 |
function demo_reset($filename = 'demo_site', $verbose = TRUE) {
|
| 223 |
$fileconfig = demo_get_fileconfig($filename);
|
| 224 |
if (!file_exists($fileconfig['sqlfile']) || !($fp = fopen($fileconfig['sqlfile'], 'r'))) {
|
| 225 |
if ($verbose) {
|
| 226 |
drupal_set_message(t('Unable to open dump file %filename.', array('%filename' => $fileconfig['sqlfile'])), 'error');
|
| 227 |
}
|
| 228 |
watchdog('demo', 'Unable to open dump file %filename.', array('%filename' => $fileconfig['sqlfile']), WATCHDOG_ERROR);
|
| 229 |
return FALSE;
|
| 230 |
}
|
| 231 |
|
| 232 |
// Load any database information in front of reset.
|
| 233 |
$demo_dump_cron = variable_get('demo_dump_cron', $filename);
|
| 234 |
$version = demo_get_info($fileconfig['infofile'], 'version');
|
| 235 |
$is_version_1_0_dump = version_compare($version, '1.1', '<');
|
| 236 |
|
| 237 |
if (file_exists($fileconfig['sqlfile']) && $fp = fopen($fileconfig['sqlfile'], 'r')) {
|
| 238 |
// Drop tables
|
| 239 |
$dt_watchdog = DatabaseConnection::prefixTables('{watchdog}');
|
| 240 |
foreach (demo_enum_tables() as $table) {
|
| 241 |
// Skip watchdog, except for legacy dumps that included the watchdog table
|
| 242 |
if ($table != $dt_watchdog || $is_version_1_0_dump) {
|
| 243 |
db_query("DROP TABLE $table");
|
| 244 |
}
|
| 245 |
}
|
| 246 |
|
| 247 |
// Load data from snapshot
|
| 248 |
$query = '';
|
| 249 |
$success = TRUE;
|
| 250 |
while (!feof($fp)) {
|
| 251 |
$line = fgets($fp, 16384);
|
| 252 |
if ($line && $line != "\n" && strncmp($line, '--', 2) && strncmp($line, '#', 1)) {
|
| 253 |
$query .= $line;
|
| 254 |
if (substr($line, -2) == ";\n") {
|
| 255 |
$options = array(
|
| 256 |
'target' => 'default',
|
| 257 |
'return' => Database::RETURN_NULL,
|
| 258 |
// 'throw_exception' => FALSE,
|
| 259 |
);
|
| 260 |
$stmt = Database::getConnection($options['target'])->prepare($query);
|
| 261 |
if (!$stmt->execute(array(), $options)) {
|
| 262 |
if ($verbose) {
|
| 263 |
// Don't use t() here, as the locale_* tables might not (yet) exist.
|
| 264 |
drupal_set_message(strtr('Query failed: %query', array('%query' => $query)), 'error');
|
| 265 |
}
|
| 266 |
$success = FALSE;
|
| 267 |
}
|
| 268 |
$query = '';
|
| 269 |
}
|
| 270 |
}
|
| 271 |
}
|
| 272 |
}
|
| 273 |
fclose($fp);
|
| 274 |
|
| 275 |
if ($success) {
|
| 276 |
// Allow other modules to act on successful resets.
|
| 277 |
module_invoke_all('demo_reset');
|
| 278 |
|
| 279 |
if ($verbose) {
|
| 280 |
drupal_set_message(t('Successfully restored database from %filename.', array('%filename' => $fileconfig['sqlfile'])));
|
| 281 |
}
|
| 282 |
watchdog('demo', 'Successfully restored database from %filename.', array('%filename' => $fileconfig['sqlfile']), WATCHDOG_NOTICE);
|
| 283 |
}
|
| 284 |
else {
|
| 285 |
if ($verbose) {
|
| 286 |
drupal_set_message(t('Failed restoring database from %filename.', array('%filename' => $fileconfig['sqlfile'])), 'error');
|
| 287 |
}
|
| 288 |
watchdog('demo', 'Failed restoring database from %filename.', array('%filename' => $fileconfig['sqlfile']), WATCHDOG_ERROR);
|
| 289 |
}
|
| 290 |
|
| 291 |
// Reset default dump to load on cron.
|
| 292 |
variable_set('demo_dump_cron', $demo_dump_cron);
|
| 293 |
|
| 294 |
return $success;
|
| 295 |
}
|
| 296 |
|
| 297 |
function demo_get_fileconfig($filename = 'demo_site') {
|
| 298 |
// Build dump path.
|
| 299 |
$fileconfig['path'] = variable_get('demo_dump_path', file_directory_path('private') . '/demo');
|
| 300 |
$fileconfig['dumppath'] = $fileconfig['path'];
|
| 301 |
// Append site name if it is not included in file_directory_path() and if not
|
| 302 |
// storing files in sites/all/files.
|
| 303 |
$fileconfig['site'] = str_replace('sites', '', conf_path());
|
| 304 |
if (strpos($fileconfig['path'], conf_path()) === FALSE && strpos($fileconfig['path'], '/all/') === FALSE) {
|
| 305 |
$fileconfig['dumppath'] .= $fileconfig['site'];
|
| 306 |
}
|
| 307 |
|
| 308 |
// Check if directory exists.
|
| 309 |
file_prepare_directory($fileconfig['path'], FILE_CREATE_DIRECTORY, 'path');
|
| 310 |
if (!file_prepare_directory($fileconfig['dumppath'], FILE_CREATE_DIRECTORY, 'path')) {
|
| 311 |
return FALSE;
|
| 312 |
}
|
| 313 |
|
| 314 |
// Protect dump files.
|
| 315 |
file_create_htaccess($fileconfig['path'], TRUE);
|
| 316 |
|
| 317 |
// Build SQL filename.
|
| 318 |
$fileconfig['sql'] = $filename . '.sql';
|
| 319 |
$fileconfig['sqlfile'] = $fileconfig['dumppath'] . '/' . $fileconfig['sql'];
|
| 320 |
|
| 321 |
// Build info filename.
|
| 322 |
$fileconfig['info'] = $filename . '.info';
|
| 323 |
$fileconfig['infofile'] = $fileconfig['dumppath'] . '/' . $fileconfig['info'];
|
| 324 |
|
| 325 |
return $fileconfig;
|
| 326 |
}
|
| 327 |
|
| 328 |
function demo_get_dumps() {
|
| 329 |
$fileconfig = demo_get_fileconfig();
|
| 330 |
|
| 331 |
// Fetch list of available info files
|
| 332 |
$files = file_scan_directory($fileconfig['dumppath'], '/\.info$/');
|
| 333 |
|
| 334 |
foreach ($files as $file => $object) {
|
| 335 |
$files[$file]->filemtime = filemtime($file);
|
| 336 |
$files[$file]->filesize = filesize(substr($file, 0, -4) . 'sql');
|
| 337 |
}
|
| 338 |
|
| 339 |
// Sort snapshots by date (ascending file modification time)
|
| 340 |
uasort($files, create_function('$a, $b', 'return ($a->filemtime < $b->filemtime);'));
|
| 341 |
|
| 342 |
$options = array();
|
| 343 |
// Forms API does not pass selected value of individual radio buttons,
|
| 344 |
// so we manually insert an internal form value here.
|
| 345 |
$options['dump']['filename'] = array(
|
| 346 |
'#type' => 'value',
|
| 347 |
'#required' => TRUE,
|
| 348 |
'#title' => t('Snapshot'),
|
| 349 |
);
|
| 350 |
foreach ($files as $filename => $file) {
|
| 351 |
// Build basic file info
|
| 352 |
$files[$filename] = (array)$files[$filename];
|
| 353 |
$info = demo_get_info($filename);
|
| 354 |
|
| 355 |
// Convert file info for Forms API
|
| 356 |
$option = array();
|
| 357 |
$option['#type'] = 'radio';
|
| 358 |
$option['#name'] = 'filename';
|
| 359 |
$option['#title'] = $info['filename'] . ' (' . format_date($file->filemtime, 'small') . ', ' . format_size($file->filesize) . ')';
|
| 360 |
$option['#return_value'] = $info['filename'];
|
| 361 |
if ($info['filename'] == variable_get('demo_dump_cron', 'demo_site')) {
|
| 362 |
$option['#value'] = $info['filename'];
|
| 363 |
}
|
| 364 |
$option['#description'] = '';
|
| 365 |
if (!empty($info['description'])) {
|
| 366 |
$option['#description'] .= '<p>' . $info['description'] . '</p>';
|
| 367 |
}
|
| 368 |
$targs = array(
|
| 369 |
'@info-file-url' => url('demo/download/' . $file->name . '/info'),
|
| 370 |
'@sql-file-url' => url('demo/download/' . $file->name . '/sql'),
|
| 371 |
);
|
| 372 |
$option['#description'] .= '<p>' . t('Download: <a href="@info-file-url">.info file</a>, <a href="@sql-file-url">.sql file</a>', $targs) . '</p>';
|
| 373 |
if (count($info['modules']) > 1) {
|
| 374 |
// Remove required core modules and obvious modules from module list.
|
| 375 |
$info['modules'] = array_diff($info['modules'], array('block', 'filter', 'node', 'system', 'user', 'watchdog', 'demo'));
|
| 376 |
// Sort module list alphabetically.
|
| 377 |
sort($info['modules']);
|
| 378 |
$option['#description'] .= t('Modules: ') . implode(', ', $info['modules']);
|
| 379 |
}
|
| 380 |
$option['#attributes'] = array('onclick' => "jQuery('.description', this.parentNode.parentNode).slideToggle();");
|
| 381 |
|
| 382 |
$options['dump'][] = $option;
|
| 383 |
}
|
| 384 |
|
| 385 |
// Attach stylesheet to initially hide descriptions
|
| 386 |
drupal_add_js("jQuery('div.form-item div.description', jQuery('form')).hide();", array('type' => 'inline', 'scope' => 'footer'));
|
| 387 |
|
| 388 |
return $options;
|
| 389 |
}
|
| 390 |
|
| 391 |
function demo_get_info($filename, $field = NULL) {
|
| 392 |
$info = array();
|
| 393 |
|
| 394 |
if (file_exists($filename)) {
|
| 395 |
$info = parse_ini_file($filename);
|
| 396 |
|
| 397 |
if (isset($info['modules'])) {
|
| 398 |
$info['modules'] = explode(" ", $info['modules']);
|
| 399 |
}
|
| 400 |
else {
|
| 401 |
$info['modules'] = NULL;
|
| 402 |
}
|
| 403 |
|
| 404 |
if (!isset($info['version'])) {
|
| 405 |
$info['version'] = '1.0';
|
| 406 |
}
|
| 407 |
}
|
| 408 |
|
| 409 |
if (isset($field)) {
|
| 410 |
return isset($info[$field]) ? $info[$field] : NULL;
|
| 411 |
}
|
| 412 |
else {
|
| 413 |
return $info;
|
| 414 |
}
|
| 415 |
}
|
| 416 |
|
| 417 |
function demo_set_info($values = NULL) {
|
| 418 |
if (isset($values['filename']) && is_array($values)) {
|
| 419 |
// Check for valid filename
|
| 420 |
if (!preg_match('/^[-_\.a-zA-Z0-9]+$/', $values['filename'])) {
|
| 421 |
drupal_set_message(t('Dump filename %title must contain alphanumeric characters, dots, dashes and underscores only. Other characters, including blanks (spaces), are not allowed.', array('%title' => $values['filename'])), 'error');
|
| 422 |
return FALSE;
|
| 423 |
}
|
| 424 |
|
| 425 |
if (!empty($values['description'])) {
|
| 426 |
// parse_ini_file() doesn't allow certain characters in description
|
| 427 |
$s = array("\r\n", "\r", "\n", '"');
|
| 428 |
$r = array(' ', ' ', ' ', "'");
|
| 429 |
$values['description'] = str_replace($s, $r, $values['description']);
|
| 430 |
}
|
| 431 |
else {
|
| 432 |
// If new description is empty, try to use previous description.
|
| 433 |
$old_file = demo_get_fileconfig($values['filename']);
|
| 434 |
$old_description = demo_get_info($old_file['infofile'], 'description');
|
| 435 |
if (!empty($old_description)) {
|
| 436 |
$values['description'] = $old_description;
|
| 437 |
}
|
| 438 |
}
|
| 439 |
|
| 440 |
// Set values
|
| 441 |
$infos = array();
|
| 442 |
$infos['filename'] = $values['filename'];
|
| 443 |
$infos['description'] = '"' . $values['description'] . '"';
|
| 444 |
$infos['modules'] = implode(' ', module_list());
|
| 445 |
$infos['version'] = DEMO_DUMP_VERSION;
|
| 446 |
|
| 447 |
// Write information to .info file
|
| 448 |
$fileconfig = demo_get_fileconfig($values['filename']);
|
| 449 |
$infofile = fopen($fileconfig['infofile'], 'w');
|
| 450 |
foreach ($infos as $key => $info) {
|
| 451 |
fwrite($infofile, $key . ' = ' . $info . "\n");
|
| 452 |
}
|
| 453 |
fclose($infofile);
|
| 454 |
|
| 455 |
return $infos;
|
| 456 |
}
|
| 457 |
}
|
| 458 |
|
| 459 |
/**
|
| 460 |
* Returns a list of tables in the active database.
|
| 461 |
*
|
| 462 |
* Only returns tables whose prefix matches the configured one (or ones, if
|
| 463 |
* there are multiple).
|
| 464 |
*/
|
| 465 |
function demo_enum_tables() {
|
| 466 |
global $db_prefix;
|
| 467 |
|
| 468 |
$tables = array();
|
| 469 |
|
| 470 |
if (is_array($db_prefix)) {
|
| 471 |
// Create a regular expression for table prefix matching.
|
| 472 |
$rx = '/^' . implode('|', array_filter($db_prefix)) . '/';
|
| 473 |
}
|
| 474 |
else if ($db_prefix != '') {
|
| 475 |
$rx = '/^' . $db_prefix . '/';
|
| 476 |
}
|
| 477 |
|
| 478 |
switch (db_driver()) {
|
| 479 |
case 'mysql':
|
| 480 |
case 'mysqli':
|
| 481 |
$result = db_query('SHOW TABLES')->fetchCol();
|
| 482 |
break;
|
| 483 |
|
| 484 |
case 'pgsql':
|
| 485 |
$result = db_query('SELECT table_name FROM information_schema.tables WHERE table_schema = :schema', array(':schema' => 'public'))->fetchCol();
|
| 486 |
break;
|
| 487 |
}
|
| 488 |
|
| 489 |
foreach ($result as $table) {
|
| 490 |
if (is_array($db_prefix)) {
|
| 491 |
// Check if table name matches a configured prefix.
|
| 492 |
if (preg_match($rx, $table, $matches)) {
|
| 493 |
$table_prefix = $matches[0];
|
| 494 |
$plain_table = substr($table, strlen($table_prefix));
|
| 495 |
if ($db_prefix[$plain_table] == $table_prefix || $db_prefix['default'] == $table_prefix) {
|
| 496 |
$tables[] = $table;
|
| 497 |
}
|
| 498 |
}
|
| 499 |
}
|
| 500 |
else if ($db_prefix != '') {
|
| 501 |
if (preg_match($rx, $table)) {
|
| 502 |
$tables[] = $table;
|
| 503 |
}
|
| 504 |
}
|
| 505 |
else {
|
| 506 |
$tables[] = $table;
|
| 507 |
}
|
| 508 |
}
|
| 509 |
|
| 510 |
return $tables;
|
| 511 |
}
|
| 512 |
|
| 513 |
/**
|
| 514 |
* Retrieve a pipe delimited string of autocomplete suggestions for existing
|
| 515 |
* snapshot names.
|
| 516 |
*/
|
| 517 |
function demo_autocomplete($string = '') {
|
| 518 |
$matches = array();
|
| 519 |
if ($string && $fileconfig = demo_get_fileconfig()) {
|
| 520 |
$string = preg_quote($string);
|
| 521 |
$files = file_scan_directory($fileconfig['dumppath'], '/' . $string . '.*\.info$/');
|
| 522 |
foreach ($files as $file) {
|
| 523 |
$matches[$file->name] = check_plain($file->name);
|
| 524 |
}
|
| 525 |
}
|
| 526 |
drupal_json_output($matches);
|
| 527 |
}
|
| 528 |
|
| 529 |
/**
|
| 530 |
* Transfer (download) a snapshot file.
|
| 531 |
*
|
| 532 |
* @param $filename
|
| 533 |
* The snapshot filename to transfer.
|
| 534 |
* @param $type
|
| 535 |
* The file type, i.e. extension to transfer.
|
| 536 |
*
|
| 537 |
* @todo Allow to download an bundled archive of snapshot files.
|
| 538 |
*/
|
| 539 |
function demo_download($filename, $type) {
|
| 540 |
$fileconfig = demo_get_fileconfig($filename);
|
| 541 |
if (!isset($fileconfig[$type . 'file']) || !file_exists($fileconfig[$type . 'file'])) {
|
| 542 |
return MENU_NOT_FOUND;
|
| 543 |
}
|
| 544 |
// Force the client to re-download and trigger a file save download.
|
| 545 |
$headers = array(
|
| 546 |
'Cache-Control: private',
|
| 547 |
'Content-Type: application/octet-stream',
|
| 548 |
'Content-Length: ' . filesize($fileconfig[$type . 'file']),
|
| 549 |
'Content-Disposition: attachment, filename=' . $fileconfig[$type],
|
| 550 |
);
|
| 551 |
file_transfer($fileconfig[$type . 'file'], $headers);
|
| 552 |
}
|
| 553 |
|
| 554 |
/**
|
| 555 |
* Sets a specific snapshot as default for cron runs or the site reset block.
|
| 556 |
*
|
| 557 |
* @param $filename
|
| 558 |
* The filename of the snapshot.
|
| 559 |
*/
|
| 560 |
function demo_set_default($filename) {
|
| 561 |
variable_set('demo_dump_cron', $filename);
|
| 562 |
drupal_set_message(t('Snapshot %title will be used for upcoming cron runs.', array('%title' => $filename)));
|
| 563 |
}
|
| 564 |
|