first import

This commit is contained in:
Bachir Soussi Chiadmi
2015-04-08 11:40:19 +02:00
commit 1bc61b12ad
8435 changed files with 1582817 additions and 0 deletions

View File

@@ -0,0 +1,122 @@
// $Id: CHANGELOG.txt,v 1.57 2011/01/09 03:25:29 sun Exp $
Demo 7.x-1.x, xxxx-xx-xx
------------------------
Demo 7.x-1.0, 2010-01-09
------------------------
#915936 by sun: Updated for easier radios/checkboxes options.
#759584 by sun: Revamped administration pages.
#901954 by sun: Updated for removed file_directory_path().
by sun: Updated for new Drupal core cache tables.
by sun: Added list of system variables to retain after reset.
by sun: Added proper Drupal behavior for collapsible snapshots.
#866700 by sun: Updated for $db_prefix.
#688840 by sun: Updated for new configure link on modules page.
by sun: Updated for renamed DRUPAL_NO_CACHE constant.
#584988 by sun: Fixed paths in README.txt.
by sun: Updated for new File API, Database API, Form API, and removed registry.
#345866 by sun: Updated for removed $op in hook_block().
#521474 by sun: Updated for admin/build renamed to admin/structure.
#361301 by cwgordon7: Updated/Fixed reset functionality.
by sun: Fixed PHP notices for non-existing key $meta->native_type.
by sun: Updated for drupal_add_js().
#361301 by sun: Ported to 7.x.
Demo 6.x-1.x, xxxx-xx-xx
------------------------
#312215 by sethfisher, sun: Fixed foreign key checks prevent dropping of tables.
#765186 by sun: Fixed collation not dumped for tables.
by sun: Fixed file permissions of new .info and .sql files.
#294879 by sun: Splitted module into API and demo_reset module.
#375507 by sun: Added hook_uninstall().
by sun: Fixed table engine, charset, and comment not contained in snapshot.
#505800 by smk-ka: Fixed SQL VIEWS are causing faulty dump.
#535754 by smk-ka, sun: Added API functions/hooks to perform dumps and resets.
by sun: Fixed length of form button captions on snapshot management form.
#370402 by sun: Added option to download snapshot files.
#496620 by evoltech: Fixed paths in README.txt.
by smk-ka: Added admin_menu cache table to exclude list.
#489666 by stella: Added hook invocation after successful reset.
by sun: Fixed coding-style.
#256714 by sun: Fixed site name sub-folder no longer appended.
#256714 by smk-ka, sun: Removed site name sub-folder from dump directory path.
#393186 by sun: Fixed fatal error: Only variables can be passed by reference.
#372113 by sun: Fixed not all cache tables are skipped.
Demo 6.x-1.2, 2009-02-06
------------------------
by smk-ka: Made watchdog messages translatable (fixed a potx warning).
#369711 by smk-ka: Added confirmation before deleting a snapshot.
#369642 by smk-ka: Added checkbox to define new snapshot as default.
#329182 by sun: Moved menu items below admin/build.
#299841 by sun: Fixed wrong function arguments for watchdog().
#286781 by alex_b: Added function return value for demo_reset().
#272820 by sun: Increased maxlength for snapshot file names.
#269561 by smk-ka: Performance: Disable indices to speed up import.
#272526 by smk-ka: Added file size to snapshot list.
#268056 by sun: Fixed incomplete snapshots due to max_execution_time reached.
#265801 by smk-ka: Added exclusion of data in cache tables for snapshots.
#312215 by rondp: Added foreign key support.
#294879 by smk-ka: Moved admin functions into include file.
Demo 6.x-1.1, 2008-04-29
------------------------
#226135 by smk-ka: Added MySQLi support. Setting SQL_MODE for new dumps to
avoid generating auto values when encountering a zero value for a serial
field.
by smk-ka: Fixed generation of table list for multiple database prefixes.
Demo 6.x-1.0, 2008-02-14
------------------------
#221386 by sun: Ported Demo Site to Drupal 6.
Demo 5.x-1.3, 2008-02-24
------------------------
by smk-ka: Export excluded tables' structure (using IF NOT EXISTS) to facilitate
the creation of a new site from an exsiting demo dump.
Demo 5.x-1.2, 2007-11-15
------------------------
#191179 by sun: Fixed no information displayed after saving settings.
Fixed the new version check for legacy dumps.
Fixed wrong revision tagged with 5.x-1.1.
Demo 5.x-1.1, 2007-11-11
------------------------
Added translation template and German translation.
#175498 by smk-ka: Added version number to dumps to distinguish new-style from
legacy dumps that included the watchdog table.
Added sort snapshots by date.
#163309 by dman: Demo directory is not created on first run config.
#132753 by smk-ka: Removed dependency on dba module.
Excluding watchdog table from dump/restore. Watchdog will stay intact even after
restore.
Added snapshot name autocomplete feature.
Added usage of previous snapshot description if identical filename already
exists.
Added removal of core modules and sorting of modules in module list.
Fixed malformed serialized strings after reset
(see http://drupal.org/node/106576).
Added 'Reset now' block.
#132470 by sun: Added support for multiple snapshots.
Added multisite support.
#132455 by sun: Fixed New tables are not deleted at reset.
Fixed default dump path for not configured sites (now files/demo).
Fixed status dates in settings on a fresh installation.
Fixed storage of last reset time in status of module settings.
Demo 5.x-1.0, 2007-03-28
------------------------
Initial commit of Demo module.

View File

@@ -0,0 +1,274 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave,
Cambridge, MA 02139, USA. Everyone is permitted to copy and distribute
verbatim copies of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your freedom to
share and change it. By contrast, the GNU General Public License is
intended to guarantee your freedom to share and change free software--to
make sure the software is free for all its users. This General Public License
applies to most of the Free Software Foundation's software and to any other
program whose authors commit to using it. (Some other Free Software
Foundation software is covered by the GNU Library General Public License
instead.) You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our
General Public Licenses are designed to make sure that you have the
freedom to distribute copies of free software (and charge for this service if
you wish), that you receive source code or can get it if you want it, that you
can change the software or use pieces of it in new free programs; and that
you know you can do these things.
To protect your rights, we need to make restrictions that forbid anyone to
deny you these rights or to ask you to surrender the rights. These restrictions
translate to certain responsibilities for you if you distribute copies of the
software, or if you modify it.
For example, if you distribute copies of such a program, whether gratis or for
a fee, you must give the recipients all the rights that you have. You must make
sure that they, too, receive or can get the source code. And you must show
them these terms so they know their rights.
We protect your rights with two steps: (1) copyright the software, and (2)
offer you this license which gives you legal permission to copy, distribute
and/or modify the software.
Also, for each author's protection and ours, we want to make certain that
everyone understands that there is no warranty for this free software. If the
software is modified by someone else and passed on, we want its recipients
to know that what they have is not the original, so that any problems
introduced by others will not reflect on the original authors' reputations.
Finally, any free program is threatened constantly by software patents. We
wish to avoid the danger that redistributors of a free program will individually
obtain patent licenses, in effect making the program proprietary. To prevent
this, we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.
The precise terms and conditions for copying, distribution and modification
follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND
MODIFICATION
0. This License applies to any program or other work which contains a notice
placed by the copyright holder saying it may be distributed under the terms
of this General Public License. The "Program", below, refers to any such
program or work, and a "work based on the Program" means either the
Program or any derivative work under copyright law: that is to say, a work
containing the Program or a portion of it, either verbatim or with
modifications and/or translated into another language. (Hereinafter, translation
is included without limitation in the term "modification".) Each licensee is
addressed as "you".
Activities other than copying, distribution and modification are not covered
by this License; they are outside its scope. The act of running the Program is
not restricted, and the output from the Program is covered only if its contents
constitute a work based on the Program (independent of having been made
by running the Program). Whether that is true depends on what the Program
does.
1. You may copy and distribute verbatim copies of the Program's source
code as you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice and
disclaimer of warranty; keep intact all the notices that refer to this License
and to the absence of any warranty; and give any other recipients of the
Program a copy of this License along with the Program.
You may charge a fee for the physical act of transferring a copy, and you
may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion of it,
thus forming a work based on the Program, and copy and distribute such
modifications or work under the terms of Section 1 above, provided that you
also meet all of these conditions:
a) You must cause the modified files to carry prominent notices stating that
you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in whole or in
part contains or is derived from the Program or any part thereof, to be
licensed as a whole at no charge to all third parties under the terms of this
License.
c) If the modified program normally reads commands interactively when run,
you must cause it, when started running for such interactive use in the most
ordinary way, to print or display an announcement including an appropriate
copyright notice and a notice that there is no warranty (or else, saying that
you provide a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this License.
(Exception: if the Program itself is interactive but does not normally print such
an announcement, your work based on the Program is not required to print
an announcement.)
These requirements apply to the modified work as a whole. If identifiable
sections of that work are not derived from the Program, and can be
reasonably considered independent and separate works in themselves, then
this License, and its terms, do not apply to those sections when you distribute
them as separate works. But when you distribute the same sections as part
of a whole which is a work based on the Program, the distribution of the
whole must be on the terms of this License, whose permissions for other
licensees extend to the entire whole, and thus to each and every part
regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest your rights to
work written entirely by you; rather, the intent is to exercise the right to
control the distribution of derivative or collective works based on the
Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of a
storage or distribution medium does not bring the other work under the scope
of this License.
3. You may copy and distribute the Program (or a work based on it, under
Section 2) in object code or executable form under the terms of Sections 1
and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable source
code, which must be distributed under the terms of Sections 1 and 2 above
on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three years, to give
any third party, for a charge no more than your cost of physically performing
source distribution, a complete machine-readable copy of the corresponding
source code, to be distributed under the terms of Sections 1 and 2 above on
a medium customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer to distribute
corresponding source code. (This alternative is allowed only for
noncommercial distribution and only if you received the program in object
code or executable form with such an offer, in accord with Subsection b
above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source code
means all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation and
installation of the executable. However, as a special exception, the source
code distributed need not include anything that is normally distributed (in
either source or binary form) with the major components (compiler, kernel,
and so on) of the operating system on which the executable runs, unless that
component itself accompanies the executable.
If distribution of executable or object code is made by offering access to
copy from a designated place, then offering equivalent access to copy the
source code from the same place counts as distribution of the source code,
even though third parties are not compelled to copy the source along with the
object code.
4. You may not copy, modify, sublicense, or distribute the Program except as
expressly provided under this License. Any attempt otherwise to copy,
modify, sublicense or distribute the Program is void, and will automatically
terminate your rights under this License. However, parties who have received
copies, or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
5. You are not required to accept this License, since you have not signed it.
However, nothing else grants you permission to modify or distribute the
Program or its derivative works. These actions are prohibited by law if you
do not accept this License. Therefore, by modifying or distributing the
Program (or any work based on the Program), you indicate your acceptance
of this License to do so, and all its terms and conditions for copying,
distributing or modifying the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the original
licensor to copy, distribute or modify the Program subject to these terms and
conditions. You may not impose any further restrictions on the recipients'
exercise of the rights granted herein. You are not responsible for enforcing
compliance by third parties to this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues), conditions
are imposed on you (whether by court order, agreement or otherwise) that
contradict the conditions of this License, they do not excuse you from the
conditions of this License. If you cannot distribute so as to satisfy
simultaneously your obligations under this License and any other pertinent
obligations, then as a consequence you may not distribute the Program at all.
For example, if a patent license would not permit royalty-free redistribution
of the Program by all those who receive copies directly or indirectly through
you, then the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply and
the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents or
other property right claims or to contest validity of any such claims; this
section has the sole purpose of protecting the integrity of the free software
distribution system, which is implemented by public license practices. Many
people have made generous contributions to the wide range of software
distributed through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing to
distribute software through any other system and a licensee cannot impose
that choice.
This section is intended to make thoroughly clear what is believed to be a
consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in certain
countries either by patents or by copyrighted interfaces, the original copyright
holder who places the Program under this License may add an explicit
geographical distribution limitation excluding those countries, so that
distribution is permitted only in or among countries not thus excluded. In such
case, this License incorporates the limitation as if written in the body of this
License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will be
similar in spirit to the present version, but may differ in detail to address new
problems or concerns.
Each version is given a distinguishing version number. If the Program specifies
a version number of this License which applies to it and "any later version",
you have the option of following the terms and conditions either of that
version or of any later version published by the Free Software Foundation. If
the Program does not specify a version number of this License, you may
choose any version ever published by the Free Software Foundation.
10. If you wish to incorporate parts of the Program into other free programs
whose distribution conditions are different, write to the author to ask for
permission. For software which is copyrighted by the Free Software
Foundation, write to the Free Software Foundation; we sometimes make
exceptions for this. Our decision will be guided by the two goals of
preserving the free status of all derivatives of our free software and of
promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE,
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT
PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
NECESSARY SERVICING, REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR
AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR
ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OR INABILITY TO USE THE
PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
OR DATA BEING RENDERED INACCURATE OR LOSSES
SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN
IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS

View File

@@ -0,0 +1,65 @@
/* $Id: README.txt,v 1.7 2009/11/09 18:21:28 sun Exp $ */
-- SUMMARY --
Demo Site is a simple module that allows you to take a snapshot of a Drupal
demonstration site. It turns a Drupal installation into a sandbox that you can
use for testing modules or publicly demonstrating a module / extension / theme
(you name it). In short: With cron enabled, the Drupal site will be reset to
the dumped state in a definable interval. Of course you can reset the site
manually, too.
For a full description visit the project page:
http://drupal.org/project/demo
Bug reports, feature suggestions and latest developments:
http://drupal.org/project/issues/demo
-- REQUIREMENTS --
* Cron.
-- INSTALLATION --
* Copy the Demo module to your modules directory and enable it on the Modules
page (admin/structure/modules).
* Optionally configure who is allowed to administer Demo module, create dumps
and reset the site on the Permissions page (admin/config/people/permissions).
-- CONFIGURATION --
* Configure the path where dumps will be stored at the Dump settings
(admin/structure/demo).
To configure automatic reset:
* Go to Manage snapshots (admin/structure/demo/manage) and select a snapshot
for cron.
* Enable atomatic reset from Dump settings (admin/structure/demo). Make sure you
have cron configured to run at least once within the entered time interval.
-- USAGE --
* Go to Create snapshot (admin/structure/demo/dump) and create your first
snapshot.
* After a while, reset your site (admin/structure/demo/reset).
-- CONTACT --
Current maintainers:
* Daniel F. Kudwien (sun) - dev@unleashedmind.com
* Stefan M. Kudwien (smk-ka) - dev@unleashedmind.com
This project has been sponsored by:
* UNLEASHED MIND
Specialized in consulting and planning of Drupal powered sites, UNLEASHED
MIND offers installation, development, theming, customization, and hosting
to get you started. Visit http://www.unleashedmind.com for more information.

View File

@@ -0,0 +1,339 @@
<?php
// $Id: database_mysql_dump.inc,v 1.20 2010/09/04 00:24:29 sun Exp $
// Some older mysql client libs are missing this constant.
if (!defined('MYSQLI_BINARY_FLAG')) {
define('MYSQLI_BINARY_FLAG', 128);
}
/**
* Dump active database.
*
* @param $filename
* The filename including path to write the dump to.
* @param $options
* An associative array of snapshot options, as described in demo_dump().
*/
function demo_dump_db($filename, $options = array()) {
// Make sure we have permission to save our backup file.
$directory = dirname($filename);
if (!file_prepare_directory($directory, FILE_CREATE_DIRECTORY)) {
return FALSE;
}
if ($fp = fopen($filename, 'wb')) {
$header = array();
$header[] = '-- Demo module database dump';
$header[] = '-- Version ' . DEMO_DUMP_VERSION;
$header[] = '-- http://drupal.org/project/demo';
$header[] = '--';
$header[] = '-- Database: ' . _demo_get_database();
$header[] = '-- Date: ' . format_date(REQUEST_TIME, 'small');
$header[] = '-- Server version: ' . db_query('SELECT version()')->fetchField();
$header[] = '-- PHP version: ' . PHP_VERSION;
$header[] = '-- Drupal version: ' . VERSION;
// Avoid auto value for zero values (required for user id 0).
$header[] = '';
$header[] = 'SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";';
// Temporarily disable foreign key checks for the time of import.
$header[] = 'SET FOREIGN_KEY_CHECKS = 0;';
$header[] = '';
// Set collations for the import. PMA and mysqldump use conditional comments
// to exclude MySQL <4.1, but D6 requires >=4.1.
$header[] = 'SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT;';
$header[] = 'SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS;';
$header[] = 'SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION;';
$header[] = 'SET NAMES utf8;';
$header[] = '';
fwrite($fp, implode("\n", $header));
foreach ($options['tables'] as $table => $dump_options) {
if (!_demo_table_is_view($table)) {
if ($dump_options['schema']) {
_demo_dump_table_schema($fp, $table);
}
if ($dump_options['data']) {
_demo_dump_table_data($fp, $table);
}
}
}
$footer = array();
$footer[] = '';
// Re-enable foreign key checks.
$footer[] = 'SET FOREIGN_KEY_CHECKS = 1;';
// Revert collations for potential subsequent database queries not belonging
// to this module.
// @todo Double-check this behavior according to the results of
// http://drupal.org/node/772678
$footer[] = 'SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT;';
$footer[] = 'SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS;';
$footer[] = 'SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION;';
$footer[] = '';
$footer[] = '';
fwrite($fp, implode("\n", $footer));
fclose($fp);
return TRUE;
}
return FALSE;
}
/**
* Returns the name of the active database.
*/
function _demo_get_database() {
$database = array_keys(db_query('SHOW TABLES')->fetchAssoc());
$database = preg_replace('/^Tables_in_/i', '', $database[0]);
return $database;
}
/**
* Enumerate database tables.
*/
function _demo_enum_tables() {
return db_query('SHOW TABLES')->fetchCol();
}
/**
* Dump table schema.
*
* @param $fp
* The file handle of the output file.
* @param $table
* A table name to export the schema for.
*/
function _demo_dump_table_schema($fp, $table) {
$output = "\n";
$output .= "--\n";
$output .= "-- Table structure for table '$table'\n";
$output .= "--\n\n";
$data = db_query("SHOW CREATE TABLE `$table`")->fetchAssoc();
$status = db_query('SHOW TABLE STATUS LIKE :table', array(':table' => $table))->fetchAssoc();
// Column keys in $status start with a lower-case letter in PDO and with a
// upper-case letter otherwise. We convert all to lower-case.
foreach ($status as $key => $value) {
$key_lower = strtolower($key);
if ($key[0] != $key_lower[0]) {
$status[$key_lower] = $value;
unset($status[$key]);
}
}
// Add IF NOT EXISTS to CREATE TABLE, replace double quotes with MySQL quotes.
$output .= preg_replace(
array('/^CREATE TABLE/', '/"/'),
array('CREATE TABLE IF NOT EXISTS', '`'),
$data['create table']
);
// @todo Rethink the following code. Perhaps try to strip + parse the existing
// table definition (after leading ")" on last line) and merge anything
// missing into it, and re-append it again. There are too many differences
// between MySQL 5.0 and 5.1+, and PHP mysql(i) and pdo_mysql extensions.
// PDO is missing the table engine.
if (!strpos($output, ' ENGINE=')) {
$output .= ' ENGINE=' . $status['engine'];
}
// Always add charset and collation info to table definitions.
// SHOW CREATE TABLE does not contain collation information, if the collation
// is equal to the default collation of the connection. Since dumps can be
// moved across servers, we need to ensure correct collations.
// Note that [DEFAULT] CHARSET or [DEFAULT] CHARACTER SET is always contained
// on MySQL 5.1, even if it is equal to the default.
// This addition assumes that a collation specified for a table is taken over
// for the table's columns. The MySQL manual does not state whether this is
// the case, but manual tests confirmed that it works that way.
// Like Drupal core, we need to enforce UTF8 as character set and
// utf8_general_ci as default database collation, if not overridden via
// settings.php.
if (!strpos($output, 'COLLATE=')) {
// Only if the collation contains a underscore, the first string up to the
// first underscore is the character set.
// @see PMA_exportDBCreate()
if (strpos($status['collation'], '_')) {
$collate = 'COLLATE=' . $status['collation'];
}
// If there is a character set defined already, just append the collation.
if (strpos($output, 'CHARSET') || strpos($output, 'CHARACTER SET')) {
// @todo This may also hit column definitions instead of the table
// definition only. Should technically also be case-insensitive.
$output = preg_replace('@((?:DEFAULT )?(?:CHARSET|CHARACTER SET) \w+)@', '$1 ' . $collate, $output);
}
else {
$output .= ' DEFAULT CHARSET=utf8 ' . $collate;
}
}
// Add the table comment, if any.
if (!preg_match('@^\) .*COMMENT.+$@', $output) && !empty($status['comment'])) {
// On PHP 5.2.6/Win32 with PDO MySQL 5.0 with InnoDB, the table comment has
// a trailing "; InnoDB free: 84992 kB".
$status['comment'] = preg_replace('@; InnoDB free: .+$@', '', $status['comment']);
$output .= " COMMENT='" . $status['comment'] . "'";
}
// @todo Depends on whether we dump data and table existence on import.
// if (!empty($status['auto_increment'])) {
// $output .= ' AUTO_INCREMENT=' . $status['auto_increment'];
// }
$output .= ";\n";
fwrite($fp, $output);
}
/**
* Dump table data.
*
* This code has largely been stolen from the phpMyAdmin project.
*
* @param $fp
* The file handle of the output file.
* @param $table
* A table name to export the data for.
*/
function _demo_dump_table_data($fp, $table) {
$output = "\n";
$output .= "--\n";
$output .= "-- Dumping data for table '$table'\n";
$output .= "--\n\n";
// Dump table data.
$result = db_query("SELECT * FROM `$table`", array(), array('fetch' => PDO::FETCH_ASSOC));
// Get table fields.
if ($fields = _demo_get_fields($result)) {
// Disable indices to speed up import.
$output .= "/*!40000 ALTER TABLE $table DISABLE KEYS */;\n";
// Escape backslashes, PHP code, special chars
$search = array('\\', "'", "\x00", "\x0a", "\x0d", "\x1a");
$replace = array('\\\\', "''", '\0', '\n', '\r', '\Z');
$insert_cmd = "INSERT INTO `$table` VALUES\n";
$insert_buffer = '';
$current_row = 0;
$query_size = 0;
foreach ($result as $row) {
$current_row++;
$values = array();
$field = 0;
foreach ($row as $value) {
// NULL
if (!isset($value) || is_null($value)) {
$values[] = 'NULL';
}
// A number
// timestamp is numeric on some MySQL 4.1, BLOBs are sometimes numeric
else if ($fields[$field]->numeric && !$fields[$field]->timestamp && !$fields[$field]->blob) {
$values[] = $value;
}
// A true BLOB
// - mysqldump only generates hex data when the --hex-blob
// option is used, for fields having the binary attribute
// no hex is generated
// - a TEXT field returns type blob but a real blob
// returns also the 'binary' flag
else if ($fields[$field]->binary && $fields[$field]->blob) {
// Empty blobs need to be different, but '0' is also empty :-(
if (empty($value) && $value != '0') {
$values[] = "''";
}
else {
$values[] = '0x' . bin2hex($value);
}
}
// Something else -> treat as a string
else {
$values[] = "'" . str_replace($search, $replace, $value) . "'";
}
$field++;
}
if ($current_row == 1) {
$insert_buffer = $insert_cmd . '(' . implode(', ', $values) . ')';
}
else {
$insert_buffer = '(' . implode(', ', $values) . ')';
// Check if buffer size exceeds 50KB.
if ($query_size + strlen($insert_buffer) > 50000) {
// Flush to disc and start new buffer.
fwrite($fp, $output . ";\n");
$output = '';
$current_row = 1;
$query_size = 0;
$insert_buffer = $insert_cmd . $insert_buffer;
}
}
$query_size += strlen($insert_buffer);
$output .= ($current_row == 1 ? '' : ",\n") . $insert_buffer;
}
if ($current_row > 0) {
$output .= ";\n";
}
// Enable indices again.
$output .= "/*!40000 ALTER TABLE $table ENABLE KEYS */;\n";
}
fwrite($fp, $output);
}
/**
* Return table fields and their properties.
*/
function _demo_get_fields($result) {
$fields = array();
switch (db_driver()) {
case 'mysql':
$i = 0;
while ($meta = $result->getColumnMeta($i)) {
settype($meta, 'object');
// pdo_mysql does not add a native type for INT fields.
if (isset($meta->native_type)) {
// Enhance the field definition for mysql-extension compatibilty.
$meta->numeric = (strtolower($meta->native_type) == 'short');
$meta->blob = (strtolower($meta->native_type) == 'blob');
// Add custom properties.
$meta->timestamp = (strtolower($meta->native_type) == 'long');
}
else {
$meta->numeric = $meta->blob = $meta->timestamp = FALSE;
}
$meta->binary = (array_search('not_null', $meta->flags));
$fields[] = $meta;
$i++;
}
break;
}
return $fields;
}
/**
* Determine whether the given table is a VIEW.
*/
function _demo_table_is_view($table) {
static $tables = array();
if (!isset($tables[$table])) {
$status = db_query('SHOW TABLE STATUS LIKE :table', array(':table' => $table))->fetchAssoc();
$tables[$table] = (strtoupper(substr($status['comment'], 0, 4)) == 'VIEW');
}
return $tables[$table];
}

View File

@@ -0,0 +1,6 @@
/* $Id: demo.admin.css,v 1.1 2010/09/25 17:06:05 sun Exp $ */
.demo-status label {
float: left;
width: 13em;
}

View File

@@ -0,0 +1,712 @@
<?php
// $Id: demo.admin.inc,v 1.35 2011/01/09 03:11:12 sun Exp $
/**
* @file
* Demonstration Site administrative pages
*/
/**
* Current version of SQL dump structure.
*/
define('DEMO_DUMP_VERSION', '1.1');
/**
* Form builder for Demo module settings.
*/
function demo_admin_settings($form, &$form_state) {
if (!file_stream_wrapper_valid_scheme('private')) {
form_set_error('', t('The <a href="@file-settings-url">private filesystem</a> must be configured in order to create or load snapshots.', array(
'@file-settings-url' => url('admin/config/media/file-system', array(
'query' => drupal_get_destination(),
)),
)));
}
$form['demo_dump_path'] = array(
'#type' => 'textfield',
'#title' => t('Snapshot file system path'),
'#field_prefix' => 'private://',
'#default_value' => variable_get('demo_dump_path', 'demo'),
'#required' => TRUE,
);
$form['#validate'][] = 'demo_admin_settings_validate';
return system_settings_form($form);
}
/**
* Form validation handler for demo_admin_settings().
*/
function demo_admin_settings_validate($form, &$form_state) {
if (!file_prepare_directory($form_state['values']['demo_dump_path'], FILE_CREATE_DIRECTORY)) {
form_set_error('demo_dump_path', t('The snapshot directory %directory could not be created.', array('%directory' => $form_state['values']['demo_dump_path'])));
}
}
/**
* Form builder to manage snapshots.
*/
function demo_manage_form($form, &$form_state) {
$form['status'] = array(
'#type' => 'container',
'#title' => t('Status'),
'#attributes' => array(
'class' => array('demo-status', 'clearfix'),
),
'#attached' => array(
'css' => array(drupal_get_path('module', 'demo') . '/demo.admin.css'),
),
);
$reset_date = variable_get('demo_reset_last', 0);
$form['status']['reset_last'] = array(
'#type' => 'item',
'#title' => t('Last reset'),
'#markup' => $reset_date ? format_date($reset_date) : t('Never'),
);
$form['dump'] = demo_get_dumps();
$form['actions'] = array('#type' => 'actions');
$form['actions']['delete'] = array(
'#type' => 'submit',
'#value' => t('Delete'),
'#submit' => array('demo_manage_delete_submit'),
);
// If there are no snapshots yet, hide the selection and form actions.
if (empty($form['dump']['#options'])) {
$form['dump']['#access'] = FALSE;
$form['actions']['#access'] = FALSE;
}
return $form;
}
/**
* Delete button submit handler for demo_manage_form().
*/
function demo_manage_delete_submit($form, &$form_state) {
$form_state['redirect'] = 'admin/structure/demo/delete/' . $form_state['values']['filename'];
}
/**
* Form builder to confirm deletion of a snapshot.
*/
function demo_delete_confirm($form, &$form_state, $filename) {
$fileconfig = demo_get_fileconfig($filename);
if (!file_exists($fileconfig['infofile'])) {
return drupal_access_denied();
}
$form['filename'] = array(
'#type' => 'value',
'#value' => $filename,
);
return confirm_form($form, t('Are you sure you want to delete the snapshot %title?', array('%title' => $filename)), 'admin/structure/demo', t('This action cannot be undone.'), t('Delete'));
}
/**
* Form submit handler for demo_delete_confirm().
*/
function demo_delete_confirm_submit($form, &$form_state) {
$files = demo_get_fileconfig($form_state['values']['filename']);
unlink($files['sqlfile']);
unlink($files['infofile']);
drupal_set_message(t('Snapshot %title has been deleted.', array(
'%title' => $form_state['values']['filename'],
)));
$form_state['redirect'] = 'admin/structure/demo';
}
/**
* Form builder to create a new snapshot.
*/
function demo_dump_form($form, &$form_state) {
$form['#tree'] = TRUE;
$form['dump']['filename'] = array(
'#title' => t('Name'),
'#type' => 'textfield',
'#autocomplete_path' => 'demo/autocomplete',
'#required' => TRUE,
'#maxlength' => 128,
'#description' => t('Allowed characters: a-z, 0-9, dashes ("-"), underscores ("_") and dots.'),
);
$form['dump']['description'] = array(
'#title' => t('Description'),
'#type' => 'textarea',
'#rows' => 2,
'#description' => t('Leave empty to retain the existing description when replacing a snapshot.'),
);
$form['dump']['tables'] = array(
'#type' => 'value',
'#value' => demo_enum_tables(),
);
if (empty($form_state['demo']['dump_exists'])) {
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Create'),
);
}
else {
$form = confirm_form($form,
t('Are you sure you want to replace the existing %name snapshot?', array(
'%name' => $form_state['values']['dump']['filename'],
)),
'admin/structure/demo',
t('A snapshot with the same name already exists and will be replaced. This action cannot be undone.')
);
}
return $form;
}
/**
* Form validation handler for demo_dump_form().
*/
function demo_dump_form_validate(&$form, &$form_state) {
if (empty($form_state['values']['confirm'])) {
$fileconfig = demo_get_fileconfig($form_state['values']['dump']['filename']);
if (file_exists($fileconfig['infofile']) || file_exists($fileconfig['sqlfile'])) {
$form_state['demo']['dump_exists'] = TRUE;
$form_state['rebuild'] = TRUE;
}
}
}
/**
* Form submit handler for demo_dump_form().
*/
function demo_dump_form_submit($form, &$form_state) {
if ($fileconfig = _demo_dump($form_state['values']['dump'])) {
drupal_set_message(t('Snapshot %filename has been created.', array(
'%filename' => $form_state['values']['dump']['filename'],
)));
}
$form_state['redirect'] = 'admin/structure/demo';
}
/**
* Create a new snapshot.
*
* @param $options
* A structured array of snapshot options:
* - filename: The base output filename, without extension.
* - default: Whether to set this dump as new default snapshot.
* - description: A description for the snapshot. If a snapshot with the same
* name already exists and this is left blank, the new snapshot will reuse
* the existing description.
* - tables: An array of tables to dump, keyed by table name (including table
* prefix, if any). The value is an array of dump options:
* - schema: Whether to dump the table schema.
* - data: Whether to dump the table data.
*/
function _demo_dump($options) {
// Load database specific functions.
if (!demo_load_include()) {
return FALSE;
}
// Increase PHP's max_execution_time for large dumps.
drupal_set_time_limit(600);
// Generate the info file.
$info = demo_set_info($options);
if (!$info) {
return FALSE;
}
// Allow other modules to alter the dump options.
$fileconfig = demo_get_fileconfig($info['filename']);
drupal_alter('demo_dump', $options, $info, $fileconfig);
// Perform database dump.
if (!demo_dump_db($fileconfig['sqlfile'], $options)) {
return FALSE;
}
// Adjust file permissions.
drupal_chmod($fileconfig['infofile']);
drupal_chmod($fileconfig['sqlfile']);
// Allow other modules to act on successful dumps.
module_invoke_all('demo_dump', $options, $info, $fileconfig);
return $fileconfig;
}
/**
* Form builder to reset site to a snapshot.
*/
function demo_reset_confirm($form, &$form_state) {
$form['dump'] = demo_get_dumps();
$form['warning'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array('messages', 'warning'),
),
);
$form['warning']['message'] = array(
'#markup' => t('This action cannot be undone.'),
);
return confirm_form($form,
t('Are you sure you want to reset the site?'),
'admin/structure/demo',
t('Overwrites all changes that made to this site since the chosen snapshot.'),
t('Reset')
);
}
/**
* Form submit handler for demo_reset_confirm().
*/
function demo_reset_confirm_submit($form, &$form_state) {
// Reset site to chosen snapshot.
_demo_reset($form_state['values']['filename']);
// Do not redirect from the reset confirmation form by default, as it is
// likely that the user wants to reset all over again (e.g., keeping the
// browser tab open).
}
/**
* Reset site using snapshot.
*
* @param $filename
* Base snapshot filename, without extension.
* @param $verbose
* Whether to output status messages.
*/
function _demo_reset($filename, $verbose = TRUE) {
// Load database specific functions.
if (!demo_load_include()) {
return FALSE;
}
// Increase PHP's max_execution_time for large dumps.
drupal_set_time_limit(600);
$fileconfig = demo_get_fileconfig($filename);
if (!file_exists($fileconfig['sqlfile']) || !($fp = fopen($fileconfig['sqlfile'], 'r'))) {
if ($verbose) {
drupal_set_message(t('Unable to read file %filename.', array(
'%filename' => $fileconfig['sqlfile'],
)), 'error');
}
watchdog('demo', 'Unable to read file %filename.', array('%filename' => $fileconfig['sqlfile']), WATCHDOG_ERROR);
return FALSE;
}
// Load any database information in front of reset.
$info = demo_get_info($fileconfig['infofile']);
module_invoke_all('demo_reset_before', $filename, $info, $fileconfig);
// Retain special variables, so the (demonstration) site keeps operating after
// the reset. Specify NULL instead of default values, so unconfigured
// variables are not retained, resp., deleted after the reset.
$variables = array(
// Without the snapshot path, subsequent resets will not work.
'demo_dump_path' => variable_get('demo_dump_path', NULL),
);
// Temporarily disable foreign key checks for the time of import and before
// dropping existing tables. Foreign key checks should already be re-enabled
// as one of the last operations in the SQL dump file.
// @see demo_dump_db()
db_query("SET FOREIGN_KEY_CHECKS = 0;");
// Drop tables.
$is_version_1_0_dump = version_compare($info['version'], '1.1', '<');
$watchdog = Database::getConnection()->prefixTables('{watchdog}');
foreach (demo_enum_tables() as $table => $dump_options) {
// Skip watchdog, except for legacy dumps that included the watchdog table
if ($table != $watchdog || $is_version_1_0_dump) {
db_query("DROP TABLE $table");
}
}
// Load data from snapshot.
$success = TRUE;
$query = '';
while (!feof($fp)) {
$line = fgets($fp, 16384);
if ($line && $line != "\n" && strncmp($line, '--', 2) && strncmp($line, '#', 1)) {
$query .= $line;
if (substr($line, -2) == ";\n") {
$options = array(
'target' => 'default',
'return' => Database::RETURN_NULL,
// 'throw_exception' => FALSE,
);
$stmt = Database::getConnection($options['target'])->prepare($query);
if (!$stmt->execute(array(), $options)) {
if ($verbose) {
// Don't use t() here, as the locale_* tables might not (yet) exist.
drupal_set_message(strtr('Query failed: %query', array('%query' => $query)), 'error');
}
$success = FALSE;
}
$query = '';
}
}
}
fclose($fp);
// Retain variables.
foreach ($variables as $key => $value) {
if (isset($value)) {
variable_set($key, $value);
}
else {
variable_del($key);
}
}
if ($success) {
if ($verbose) {
drupal_set_message(t('Restored site from %filename.', array('%filename' => $fileconfig['sqlfile'])));
}
watchdog('demo', 'Restored site from %filename.', array('%filename' => $fileconfig['sqlfile']), WATCHDOG_NOTICE);
// Allow other modules to act on successful resets.
module_invoke_all('demo_reset', $filename, $info, $fileconfig);
}
else {
if ($verbose) {
drupal_set_message(t('Failed to restore site from %filename.', array('%filename' => $fileconfig['sqlfile'])), 'error');
}
watchdog('demo', 'Failed to restore site from %filename.', array('%filename' => $fileconfig['sqlfile']), WATCHDOG_ERROR);
}
// Save request time of last reset, but not during re-installation via
// demo_profile.
if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE !== 'install') {
variable_set('demo_reset_last', REQUEST_TIME);
}
return $success;
}
function demo_get_fileconfig($filename = 'demo_site') {
$fileconfig = array();
// Build dump path.
if (!file_stream_wrapper_valid_scheme('private')) {
// @todo Temporarily throwing a form error here.
// Don't break demo_profile.
if (!defined('MAINTENANCE_MODE')) {
form_set_error('', t('The <a href="@file-settings-url">private filesystem</a> must be configured in order to create or load snapshots.', array(
'@file-settings-url' => url('admin/config/media/file-system', array(
'query' => drupal_get_destination(),
)),
)));
}
return FALSE;
}
$fileconfig['path'] = 'private://' . variable_get('demo_dump_path', 'demo');
$fileconfig['dumppath'] = $fileconfig['path'];
// @todo Update to D7?
// Append site name if it is not included in file_directory_path() and if not
// storing files in sites/all/files.
$fileconfig['site'] = str_replace('sites', '', conf_path());
/*
if (strpos($fileconfig['path'], conf_path()) === FALSE && strpos($fileconfig['path'], '/all/') === FALSE) {
$fileconfig['dumppath'] .= $fileconfig['site'];
}
*/
// Check if directory exists.
if (!file_prepare_directory($fileconfig['dumppath'], FILE_CREATE_DIRECTORY)) {
return FALSE;
}
// Protect dump files.
file_create_htaccess($fileconfig['path'], TRUE);
// Build SQL filename.
$fileconfig['sql'] = $filename . '.sql';
$fileconfig['sqlfile'] = $fileconfig['dumppath'] . '/' . $fileconfig['sql'];
// Build info filename.
$fileconfig['info'] = $filename . '.info';
$fileconfig['infofile'] = $fileconfig['dumppath'] . '/' . $fileconfig['info'];
return $fileconfig;
}
/**
* Load database specific functions.
*/
function demo_load_include() {
$engine = db_driver();
if (!module_load_include('inc', 'demo', 'database_' . $engine . '_dump')) {
drupal_set_message(t('@database is not supported yet.', array('@database' => ucfirst($engine))), 'error');
return FALSE;
}
return TRUE;
}
function demo_get_dumps() {
$fileconfig = demo_get_fileconfig();
// Fetch list of available info files
$files = file_scan_directory($fileconfig['dumppath'], '/\.info$/');
foreach ($files as $file => $object) {
$files[$file]->filemtime = filemtime($file);
$files[$file]->filesize = filesize(substr($file, 0, -4) . 'sql');
}
// Sort snapshots by date (ascending file modification time).
uasort($files, create_function('$a, $b', 'return ($a->filemtime < $b->filemtime);'));
$element = array(
'#type' => 'radios',
'#title' => t('Snapshot'),
'#required' => TRUE,
'#parents' => array('filename'),
'#options' => array(),
'#attributes' => array(
'class' => array('demo-snapshots-widget'),
),
'#attached' => array(
'js' => array(drupal_get_path('module', 'demo') . '/demo.admin.js'),
),
);
foreach ($files as $filename => $file) {
$info = demo_get_info($filename);
// Prepare snapshot title.
$title = t('@snapshot <small>(!date, !size)</small>', array(
'@snapshot' => $info['filename'],
'!date' => format_date($file->filemtime, 'small'),
'!size' => format_size($file->filesize),
));
// Prepare snapshot description.
$description = '';
if (!empty($info['description'])) {
$description .= '<p>' . $info['description'] . '</p>';
}
// Add download links.
$description .= '<p>' . t('Download: <a href="@info-file-url">.info file</a>, <a href="@sql-file-url">.sql file</a>', array(
'@info-file-url' => url('demo/download/' . $file->name . '/info'),
'@sql-file-url' => url('demo/download/' . $file->name . '/sql'),
)) . '</p>';
// Add module list.
if (count($info['modules']) > 1) {
// Remove required core modules and Demo from module list.
$modules = array_diff($info['modules'], array('filter', 'node', 'system', 'user', 'demo'));
// Sort module list alphabetically.
sort($modules);
$description .= t('Modules: @modules', array('@modules' => implode(', ', $modules)));
}
// Add the radio option element.
$element['#options'][$info['filename']] = $title;
$element[$info['filename']] = array(
'#description' => $description,
'#file' => $file,
'#info' => $info,
);
}
return $element;
}
function demo_get_info($filename, $field = NULL) {
$info = array();
if (file_exists($filename)) {
$info = parse_ini_file($filename);
if (isset($info['modules'])) {
$info['modules'] = explode(" ", $info['modules']);
}
else {
$info['modules'] = NULL;
}
if (!isset($info['version'])) {
$info['version'] = '1.0';
}
}
if (isset($field)) {
return isset($info[$field]) ? $info[$field] : NULL;
}
else {
return $info;
}
}
function demo_set_info($values = NULL) {
if (isset($values['filename']) && is_array($values)) {
// Check for valid filename
if (!preg_match('/^[-_\.a-zA-Z0-9]+$/', $values['filename'])) {
drupal_set_message(t('Invalid filename. It must only contain alphanumeric characters, dots, dashes and underscores. Other characters, including spaces, are not allowed.'), 'error');
return FALSE;
}
if (!empty($values['description'])) {
// parse_ini_file() doesn't allow certain characters in description
$s = array("\r\n", "\r", "\n", '"');
$r = array(' ', ' ', ' ', "'");
$values['description'] = str_replace($s, $r, $values['description']);
}
else {
// If new description is empty, try to use previous description.
$old_file = demo_get_fileconfig($values['filename']);
$old_description = demo_get_info($old_file['infofile'], 'description');
if (!empty($old_description)) {
$values['description'] = $old_description;
}
}
// Set values
$infos = array();
$infos['filename'] = $values['filename'];
$infos['description'] = '"' . $values['description'] . '"';
$infos['modules'] = implode(' ', module_list());
$infos['version'] = DEMO_DUMP_VERSION;
// Write information to .info file
$fileconfig = demo_get_fileconfig($values['filename']);
$infofile = fopen($fileconfig['infofile'], 'w');
foreach ($infos as $key => $info) {
fwrite($infofile, $key . ' = ' . $info . "\n");
}
fclose($infofile);
return $infos;
}
}
/**
* Returns a list of tables in the active database.
*
* Only returns tables whose prefix matches the configured one (or ones, if
* there are multiple).
*/
function demo_enum_tables() {
$tables = array();
// Load database specific functions.
if (!demo_load_include()) {
return FALSE;
}
$connection = Database::getConnection();
$db_options = $connection->getConnectionOptions();
// Create a regex that matches the table prefix(es).
// We are only interested in non-empty table prefixes.
$prefixes = array();
if (!empty($db_options['prefix'])) {
if (is_array($db_options['prefix'])) {
$prefixes = array_filter($db_options['prefix']);
}
elseif ($db_options['prefix'] != '') {
$prefixes['default'] = $db_options['prefix'];
}
$rx = '/^' . implode('|', $prefixes) . '/';
}
// Query the database engine for the table list.
$result = _demo_enum_tables();
foreach ($result as $table) {
if (!empty($prefixes)) {
// Check if table name matches a configured prefix.
if (preg_match($rx, $table, $matches)) {
$table_prefix = $matches[0];
$plain_table = substr($table, strlen($table_prefix));
if ($prefixes[$plain_table] == $table_prefix || $prefixes['default'] == $table_prefix) {
$tables[$table] = array('schema' => TRUE, 'data' => TRUE);
}
}
}
else {
$tables[$table] = array('schema' => TRUE, 'data' => TRUE);
}
}
// Apply default exclude list.
$excludes = array(
// Drupal core.
'{cache}',
'{cache_bootstrap}',
'{cache_block}',
'{cache_content}',
'{cache_field}',
'{cache_filter}',
'{cache_form}',
'{cache_menu}',
'{cache_page}',
'{cache_path}',
'{cache_update}',
'{watchdog}',
// CTools.
'{ctools_object_cache}',
// Administration menu.
'{cache_admin_menu}',
// Panels.
'{panels_object_cache}',
// Views.
'{cache_views}',
'{cache_views_data}',
'{views_object_cache}',
);
foreach (array_map(array($connection, 'prefixTables'), $excludes) as $table) {
if (isset($tables[$table])) {
$tables[$table]['data'] = FALSE;
}
}
return $tables;
}
/**
* Retrieve a pipe delimited string of autocomplete suggestions for existing snapshots.
*/
function demo_autocomplete($string = '') {
$matches = array();
if ($string && $fileconfig = demo_get_fileconfig()) {
$string = preg_quote($string);
$files = file_scan_directory($fileconfig['dumppath'], '/' . $string . '.*\.info$/');
foreach ($files as $file) {
$matches[$file->name] = check_plain($file->name);
}
}
drupal_json_output($matches);
}
/**
* Transfer (download) a snapshot file.
*
* @param $filename
* The snapshot filename to transfer.
* @param $type
* The file type, i.e. extension to transfer.
*
* @todo Allow to download an bundled archive of snapshot files.
*/
function demo_download($filename, $type) {
$fileconfig = demo_get_fileconfig($filename);
if (!isset($fileconfig[$type . 'file']) || !file_exists($fileconfig[$type . 'file'])) {
return MENU_NOT_FOUND;
}
// Force the client to re-download and trigger a file save download.
$headers = array(
'Cache-Control: private',
'Content-Type: application/octet-stream',
'Content-Length: ' . filesize($fileconfig[$type . 'file']),
'Content-Disposition: attachment, filename=' . $fileconfig[$type],
);
file_transfer($fileconfig[$type . 'file'], $headers);
}

View File

@@ -0,0 +1,22 @@
// $Id: demo.admin.js,v 1.1 2010/08/30 14:30:49 sun Exp $
(function ($) {
/**
* Collapsible snapshots.
*/
Drupal.behaviors.demoCollapse = {
attach: function (context) {
$('.demo-snapshots-widget .form-item-filename', context).once('demo-collapse', function () {
var $item = $(this);
$item
.find('label')
.click(function () {
$item.find('.description').slideToggle('fast');
})
.end()
.find('.description').hide();
});
}
};
})(jQuery);

View File

@@ -0,0 +1,45 @@
<?php
// $Id: demo.api.php,v 1.1 2009/11/09 23:28:08 sun Exp $
/**
* @file
* Documentation for Demonstration site module.
*/
/**
* @addtogroup hooks
* @{
*/
/**
* Alter snapshot options before a snapshot is created.
*
* @param &$options
* A structured array consisting of submitted form values:
* - filename: The base output filename, without extension.
* - default: Whether to set this dump as new default snapshot.
* - description: A description for the snapshot. If a snapshot with the same
* name already exists and this is left blank, the new snapshot will reuse
* the existing description.
* - tables: An array of tables to dump, keyed by table name (including table
* prefix, if any). The value is an array of dump options:
* - schema: Whether to dump the table schema.
* - data: Whether to dump the table data.
*/
function hook_demo_dump_alter(&$options) {
// Only export the table schema of table cache_table, but not the data.
// Commonly used for cache tables.
$options['tables']['cache_table']['data'] = FALSE;
// Completely ignore tables starting with a certain prefix.
foreach ($options['tables'] as $table => $dump_options) {
// Test if the table name starts with 'unrelated_'.
if (strncmp($table, 'unrelated_', 10) == 0) {
unset($options['tables'][$table]);
}
}
}
/**
* @} End of "addtogroup hooks".
*/

View File

@@ -0,0 +1,16 @@
; $Id: demo.info,v 1.11 2010/02/19 18:21:52 sun Exp $
name = Demonstration site
description = Create snapshots and reset the site for demonstration or testing purposes.
package = Development
core = 7.x
configure = admin/structure/demo
files[] = demo.module
files[] = demo.admin.inc
files[] = database_mysql_dump.inc
; Information added by drupal.org packaging script on 2011-01-09
version = "7.x-1.0"
core = "7.x"
project = "demo"
datestamp = "1294543925"

View File

@@ -0,0 +1,42 @@
<?php
// $Id: demo.install,v 1.9 2010/09/04 02:42:26 sun Exp $
/**
* @file
* Demonstration site module installation functions.
*/
/**
* Implements hook_uninstall().
*/
function demo_uninstall() {
variable_del('demo_reset_last');
}
/**
* Move existing dumps to new directory without site name sub-folder.
*/
function demo_update_6100() {
// If file_directory_path() contains the site name already or is
// 'sites/all/files', create new folder without site name and move existing
// files to the new location.
$new_path = variable_get('demo_dump_path', file_directory_path() . '/demo');
if (strpos($new_path, conf_path()) !== FALSE || strpos($new_path, '/all/') !== FALSE) {
$old_path = $new_path . str_replace('sites', '', conf_path());
if ($new_path != $old_path && file_check_directory($old_path)) {
// Fetch list of available files.
$files = file_scan_directory($old_path, '/\.(info|sql)$/');
foreach ($files as $file) {
rename($file->filename, $new_path . '/' . $file->basename);
}
// Ignore any warnings from rmdir() about remaining files in the old
// directory (they will NOT be deleted).
@rmdir($old_path);
}
}
}
/**
* @todo Remove file_directory_path() from demo_dump_path variable.
*/

View File

@@ -0,0 +1,122 @@
<?php
// $Id: demo.module,v 1.39 2010/09/25 17:06:05 sun Exp $
/**
* @file
* Demonstration site API Drupal integration functions.
*/
/**
* Implements hook_perm().
*/
function demo_permission() {
return array(
'administer demo settings' => array(
'title' => t('Create snapshots and reset the site'),
'restrict access' => TRUE,
),
);
}
/**
* Implements hook_menu().
*/
function demo_menu() {
$admin_access = array('administer demo settings');
$items['admin/structure/demo'] = array(
'title' => 'Snapshots',
'description' => 'Create snapshots and reset the site.',
'page callback' => 'drupal_get_form',
'page arguments' => array('demo_manage_form'),
'access arguments' => $admin_access,
'file' => 'demo.admin.inc',
);
$items['admin/structure/demo/list'] = array(
'title' => 'List',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/structure/demo/dump'] = array(
'title' => 'Create snapshot',
'page callback' => 'drupal_get_form',
'page arguments' => array('demo_dump_form'),
'access arguments' => $admin_access,
'file' => 'demo.admin.inc',
'type' => MENU_LOCAL_ACTION,
);
$items['admin/structure/demo/reset'] = array(
'title' => 'Reset',
'page callback' => 'drupal_get_form',
'page arguments' => array('demo_reset_confirm'),
'access arguments' => $admin_access,
'file' => 'demo.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
$items['admin/structure/demo/delete/%'] = array(
'title' => 'Delete snapshot',
'page callback' => 'drupal_get_form',
'page arguments' => array('demo_delete_confirm', 4),
'access arguments' => $admin_access,
'file' => 'demo.admin.inc',
'type' => MENU_VISIBLE_IN_BREADCRUMB,
);
$items['admin/structure/demo/settings'] = array(
'title' => 'Settings',
'page callback' => 'drupal_get_form',
'page arguments' => array('demo_admin_settings'),
'access arguments' => $admin_access,
'file' => 'demo.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 10,
);
$items['demo/autocomplete'] = array(
'page callback' => 'demo_autocomplete',
'access arguments' => $admin_access,
'file' => 'demo.admin.inc',
'type' => MENU_CALLBACK,
);
$items['demo/download'] = array(
'page callback' => 'demo_download',
'access arguments' => $admin_access,
'file' => 'demo.admin.inc',
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Create a new snapshot.
*
* @param $options
* A structured array of snapshot options:
* - filename: The base output filename, without extension.
* - default: Whether to set this dump as new default snapshot.
* - description: A description for the snapshot. If a snapshot with the same
* name already exists and this is left blank, the new snapshot will reuse
* the existing description.
* - tables: An array of tables to dump, keyed by table name (including table
* prefix, if any). The value is an array of dump options:
* - schema: Whether to dump the table schema.
* - data: Whether to dump the table data.
*/
function demo_dump($options) {
module_load_include('inc', 'demo', 'demo.admin');
return _demo_dump($options);
}
/**
* Reset site using snapshot.
*
* @param $filename
* Base snapshot filename, without extension.
* @param $verbose
* Whether to output status messages.
*/
function demo_reset($filename, $verbose = TRUE) {
module_load_include('inc', 'demo', 'demo.admin');
return _demo_reset($filename, $verbose);
}

View File

@@ -0,0 +1,14 @@
; $Id: demo_reset.info,v 1.1 2009/11/10 05:37:52 sun Exp $
name = Demonstration site reset
description = "Allows to reset the site on cron runs and to <strong>reset the site WITHOUT CONFIRMATION.</strong> Only supposed to be used on public demonstration sites. Use at your own risk."
package = Development
core = 7.x
dependencies[] = demo
files[] = demo_reset.module
; Information added by drupal.org packaging script on 2011-01-09
version = "7.x-1.0"
core = "7.x"
project = "demo"
datestamp = "1294543925"

View File

@@ -0,0 +1,15 @@
<?php
// $Id: demo_reset.install,v 1.1 2009/11/10 05:37:52 sun Exp $
/**
* @file
* Demonstration site reset module installation functions.
*/
/**
* Implements hook_uninstall().
*/
function demo_reset_uninstall() {
variable_del('demo_dump_cron');
}

View File

@@ -0,0 +1,183 @@
<?php
// $Id: demo_reset.module,v 1.2 2010/09/25 17:06:05 sun Exp $
/**
* @file
* Demonstration site reset module.
*
* This module is supposed to be used on public Drupal demonstration sites only.
* Use at your own risk.
*/
/**
* Implements hook_form_FORMID_alter().
*/
function demo_reset_form_demo_admin_settings_alter(&$form, &$form_state) {
$intervals = array(
// 0, 5, 10, 15, 30 minutes
0, 300, 600, 900, 1800,
// 1-6, 9, 12 hours
3600, 3600 * 2, 3600 * 3, 3600 * 4, 3600 * 5, 3600 * 6, 3600 * 9, 3600 * 12,
// 1-3 days
86400, 86400 * 2, 86400 * 3,
// 1, 2, 3 weeks
604800, 604800 * 2, 604800 * 3,
// 1, 3 months
86400 * 30, 86400 * 90,
);
$intervals = drupal_map_assoc($intervals, 'format_interval');
$form['demo_reset_interval'] = array(
'#type' => 'select',
'#title' => t('Automatic reset interval'),
'#required' => FALSE,
'#default_value' => variable_get('demo_reset_interval', 0),
'#options' => $intervals,
'#empty_value' => 0,
'#description' => t('Requires a <a href="@snapshots-url">default snapshot</a> and <a href="@cron-url">cron</a> to run in the configured interval.', array(
'@snapshots-url' => url('admin/structure/demo'),
'@cron-url' => url('admin/config/system/cron'),
)),
);
}
/**
* Implements hook_form_FORMID_alter().
*/
function demo_reset_form_demo_manage_form_alter(&$form, &$form_state) {
$form['status']['demo_reset_default'] = array(
'#type' => 'item',
'#title' => t('Default snapshot'),
'#markup' => check_plain(variable_get('demo_dump_cron', t('- None -'))),
);
$demo_dump_cron = variable_get('demo_dump_cron', 'demo_site');
foreach ($form['dump'] as $name => $option) {
if ($name == $demo_dump_cron) {
$form['dump'][$name]['#value'] = $name;
break;
}
}
$form['actions']['cron'] = array(
'#type' => 'submit',
'#value' => t('Use for cron runs'),
'#submit' => array('demo_reset_demo_manage_form_submit'),
);
}
/**
* Form submit handler for demo_manage_form().
*/
function demo_reset_demo_manage_form_submit($form, &$form_state) {
demo_reset_set_default($form_state['values']['filename']);
}
/**
* Sets a specific snapshot as default for cron runs or the site reset block.
*
* @param $filename
* The filename of the snapshot.
*/
function demo_reset_set_default($filename) {
variable_set('demo_dump_cron', $filename);
drupal_set_message(t('Snapshot %title will be used for cron runs.', array('%title' => $filename)));
}
function demo_reset_form_demo_dump_form_alter(&$form, &$form_state) {
$form['dump']['default'] = array(
'#title' => t('Use as default snapshot for cron runs'),
'#type' => 'checkbox',
);
}
/**
* Implements hook_demo_dump().
*/
function demo_reset_demo_dump($options, $info, $fileconfig) {
// Set as new default snapshot.
if (!empty($options['default'])) {
demo_reset_set_default($info['filename']);
}
}
/**
* Implements hook_demo_reset().
*/
function demo_reset_demo_reset($filename, $info, $fileconfig) {
// Reset default dump to load on cron. Normally, this should be the same as
// the original value, but whenever we reset the site to a different snapshot,
// it's very unlikely that we want to reset to the previous snapshot.
variable_set('demo_dump_cron', $info['filename']);
}
/**
* Implements hook_block_list().
*/
function demo_reset_block_info() {
$blocks['reset'] = array(
'info' => t('Demonstration site reset'),
'status' => 1,
'region' => 'sidebar_second',
'cache' => DRUPAL_NO_CACHE,
);
return $blocks;
}
/**
* Implements hook_block_view().
*/
function demo_reset_block_view($delta = '') {
if (!variable_get('demo_dump_cron', '')) {
return array();
}
$block = array(
'subject' => t('Reset demo'),
'content' => drupal_get_form('demo_reset_block_form'),
);
return $block;
}
/**
* Form builder to reset site to configured snapshot.
*
* No access permission check or any condition here. By design.
*/
function demo_reset_block_form($form, &$form_state) {
$form['redirect'] = array(
'#type' => 'value',
'#value' => $_GET['q'],
);
$filename = variable_get('demo_dump_cron', '');
$form['filename'] = array(
'#type' => 'value',
'#value' => $filename,
);
$form['snapshot'] = array(
'#markup' => t('Active snapshot: @snapshot', array('@snapshot' => $filename)),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Reset now'),
);
return $form;
}
/**
* Form submit handler for demo_reset_block_form().
*/
function demo_reset_block_form_submit($form, &$form_state) {
demo_reset($form_state['values']['filename']);
$form_state['redirect'] = $form_state['values']['redirect'];
}
/**
* Implementation of hook_cron().
*/
function demo_reset_cron() {
if ($interval = variable_get('demo_reset_interval', 0)) {
// See if it's time for a reset.
if ((REQUEST_TIME - $interval) >= variable_get('demo_reset_last', 0)) {
demo_reset(variable_get('demo_dump_cron', 'demo_site'), FALSE);
}
}
}

View File

@@ -0,0 +1,208 @@
msgid ""
msgstr ""
"Project-Id-Version: demo.module\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2007-09-29 01:25+0100\n"
"Last-Translator: unleashed mind <dev@unleashedmind.com>\n"
"Language-Team: unleashed mind <dev@unleashedmind.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Language: German\n"
"X-Poedit-Country: GERMANY\n"
"X-Poedit-SourceCharset: utf-8\n"
#: demo.module:40
msgid "Demonstration site"
msgstr "Demo-Site"
#: demo.module:41
msgid "Administer reset interval, create new dumps and manually reset this site."
msgstr "Konfiguration des Zeitintervalls für automatisches Zurücksetzen, neue Schnappschüsse erstellen und manuelles Zurücksetzen der Site."
#: demo.module:48
#: ;116
msgid "Status"
msgstr "Status"
#: demo.module:54
msgid "Manage snapshots"
msgstr "Schnappschüsse verwalten"
#: demo.module:63
msgid "Create snapshot"
msgstr "Schnappschuss erstellen"
#: demo.module:72
msgid "Reset site"
msgstr "Site zurücksetzen"
#: demo.module:81
msgid "Demo Site autocomplete"
msgstr ""
#: demo.module:95
msgid "Demo site reset"
msgstr "Demo-Site zurücksetzen"
#: demo.module:104
msgid "Reset demo"
msgstr "Demo zurücksetzen"
#: demo.module:123
msgid "Never"
msgstr "Nie"
#: demo.module:126
msgid "<p><strong>Last reset:</strong> !date</p>"
msgstr "<p><strong>Zuletzt zurückgesetzt:</strong> !date</p>"
#: demo.module:129
msgid "<p><strong>Default snapshot:</strong> !snapshot</p>"
msgstr "<p><strong>Standard-Schnappschuss:</strong> !snapshot</p>"
#: demo.module:129
msgid "None"
msgstr "Keine"
#: demo.module:136
msgid "Dump settings"
msgstr "Einstellungen für Schnappschüsse"
#: demo.module:141
msgid "disabled"
msgstr "deaktiviert"
#: demo.module:144
msgid "Automatically reset site every"
msgstr "Site automatisch zurücksetzen alle"
#: demo.module:147
msgid "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."
msgstr "Zeitintervall, wie oft diese Demo-Site automatisch zurückgesetzt werden soll. Dafür zunächst einen Schnappschuss für Cron-Läufe auf der Seite <a href=\"!manage\">Schnappschüsse verwalten</a> auswählen. <strong>Hinweis:</strong> Cron muss so konfiguriert sein, dass es mindestens einmal innerhalb der gewählten Zeitspanne ausgeführt wird."
#: demo.module:152
msgid "Dump path"
msgstr "Pfad für Schnappschüsse"
#: demo.module:155
msgid "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.<br /><br /><strong>Note: For security reasons you should store site dumps outside of the document root of your webspace!</strong>"
msgstr "Beschreibbares Verzeichnis angeben, in das die Schnappschüsse für diese site gespeichert werden sollen, z.B. %files. Der Name dieser Site (d.h. %confpath) wird automatisch an den Verzeichnisnamen angehängt.<br /><br /><strong>Hinweis: Aus Sicherheitsgründen sollten Schnappschüsse immer außerhalb des Webserververzeichnisses gespeichert werden!</strong>"
#: demo.module:159
msgid "Save"
msgstr "Speichern"
#: demo.module:167
msgid "Dump could not be created. The directory %directory has not been properly configured."
msgstr "Der Schnappschuss konnte nicht erstellt werden. Das Verzeichnis %directory wurde nicht korrekt konfiguriert."
#: demo.module:178
#: ;260
msgid "Available snapshots"
msgstr "Verfügbare Schnappschüsse"
#: demo.module:183
#: ;195
msgid "Set as default snapshot for cron"
msgstr "Als Standard-Schnappschuss für Cron-Läufe festlegen"
#: demo.module:187
#: ;200
msgid "Delete selected snapshot"
msgstr "Ausgewählten Schnappschuss löschen"
#: demo.module:197
msgid "Snapshot %title will be used for upcoming cron runs."
msgstr "Der Schnappschuss %title wird für kommende Cron-Läufe verwendet."
#: demo.module:205
msgid "Snapshot %title has been deleted."
msgstr "Der Schnappschuss %title wurde gelöscht."
#: demo.module:213
msgid "File name"
msgstr "Dateiname"
#: demo.module:218
msgid "Enter the snapshot file name without file extension. Allowed characters are a-z, 0-9, dashes (\"-\"), underscores (\"_\") and dots."
msgstr "Dateiname ohne Erweiterung für den Schnappschuss eingeben. Erlaubte Zeichen sind a-z, 0-9, Bindestrich (\"-\"), Unterstrich (\"_\") und der Punkt."
#: demo.module:221
msgid "Description"
msgstr "Beschreibung"
#: demo.module:224
msgid "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."
msgstr "Optionale Angabe einer Beschreibung des Schnappschusses. Wenn keine Beschreibung angegeben wird und ein Schnappschuss mit dem selben Dateinamen bereits existiert, wird die vorherige Beschreibung übernommen."
#: demo.module:226
msgid "Are you sure you want to create a new snapshot?"
msgstr "Neuen Schnappschuss erstellen?"
#: demo.module:226
msgid "If the above filename already exists, creating a new snapshot will overwrite the existing snapshot. This action cannot be undone."
msgstr "Wenn ein Schnappschuss mit dem selben Dateinamen bereits existiert, wird der neue den alten Schnappschuss überschreiben. Diese Aktion kann nicht rückgängig gemacht werden."
#: demo.module:226
msgid "Create"
msgstr "Erstellen"
#: demo.module:226
#: ;264
msgid "Cancel"
msgstr "Abbrechen"
#: demo.module:264
msgid "Are you sure you want to reset the site?"
msgstr "Site zurücksetzen?"
#: demo.module:264
msgid "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>"
msgstr "Das Zurücksetzen der Site bewirkt, dass alle Änderungen seit der Erstellung des Schnappschusses überschrieben werden.<br /><br /><div style=\"color: red; font-weight: bold; font-size: 18px;\"><center>DIESE AKTION KANN NICHT RÜCKGÄNGIG GEMACHT WERDEN!</center><br /></div>"
#: demo.module:264
msgid "Reset"
msgstr "Zurücksetzen"
#: demo.module:291
msgid "Active snapshot: !snapshot"
msgstr "Aktiver Schnappschuss: !snapshot"
#: demo.module:295
msgid "Reset now"
msgstr "Jetzt zurücksetzen"
#: demo.module:340
msgid "Successfully restored database from %filename."
msgstr "Datenbank erfolgreich wiederhergestellt aus %filename."
#: demo.module:343
msgid "Failed restoring database from %filename."
msgstr "Konnte Datenbank nicht aus %filename wiederherstellen."
#: demo.module:354
msgid "Unable to open dump file %filename."
msgstr "Konnte die Schnappschussdatei %filename nicht öffnen."
#: demo.module:415
msgid "Snapshot"
msgstr "Schnappschuss"
#: demo.module:440
msgid "Modules: "
msgstr "Module:"
#: demo.module:483
msgid "Dump filename %title must contain alphanumeric characters, dots, dashes and underscores only. Other characters, including blanks (spaces), are not allowed."
msgstr "Der Dateiname für den Schnappschuss %title darf nur alphanumerische Zeichen, Punkte, Bindestriche und Unterstriche enthalten. Ander Zeichen, inklusive Leerzeichen, sind nicht erlaubt."
#: demo.module:348
#: ;358;0
msgid "demo"
msgstr ""
#: demo.module:27
msgid "administer demo settings"
msgstr "Demo-Site verwalten"

View File

@@ -0,0 +1,205 @@
# LANGUAGE translation of Drupal (demo.module)
# Copyright YEAR NAME <EMAIL@ADDRESS>
# Generated from file: demo.module,v 1.1.2.17 2007/09/28 23:24:01 smk
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"POT-Creation-Date: 2007-09-29 01:24+0200\n"
"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
"Last-Translator: NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
#: demo.module:40
msgid "Demonstration site"
msgstr ""
#: demo.module:41
msgid "Administer reset interval, create new dumps and manually reset this site."
msgstr ""
#: demo.module:48;116
msgid "Status"
msgstr ""
#: demo.module:54
msgid "Manage snapshots"
msgstr ""
#: demo.module:63
msgid "Create snapshot"
msgstr ""
#: demo.module:72
msgid "Reset site"
msgstr ""
#: demo.module:81
msgid "Demo Site autocomplete"
msgstr ""
#: demo.module:95
msgid "Demo site reset"
msgstr ""
#: demo.module:104
msgid "Reset demo"
msgstr ""
#: demo.module:123
msgid "Never"
msgstr ""
#: demo.module:126
msgid "<p><strong>Last reset:</strong> !date</p>"
msgstr ""
#: demo.module:129
msgid "<p><strong>Default snapshot:</strong> !snapshot</p>"
msgstr ""
#: demo.module:129
msgid "None"
msgstr ""
#: demo.module:136
msgid "Dump settings"
msgstr ""
#: demo.module:141
msgid "disabled"
msgstr ""
#: demo.module:144
msgid "Automatically reset site every"
msgstr ""
#: demo.module:147
msgid "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."
msgstr ""
#: demo.module:152
msgid "Dump path"
msgstr ""
#: demo.module:155
msgid "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.<br /><br /><strong>Note: For security reasons you should store site dumps outside of the document root of your webspace!</strong>"
msgstr ""
#: demo.module:159
msgid "Save"
msgstr ""
#: demo.module:167
msgid "Dump could not be created. The directory %directory has not been properly configured."
msgstr ""
#: demo.module:178;260
msgid "Available snapshots"
msgstr ""
#: demo.module:183;195
msgid "Set as default snapshot for cron"
msgstr ""
#: demo.module:187;200
msgid "Delete selected snapshot"
msgstr ""
#: demo.module:197
msgid "Snapshot %title will be used for upcoming cron runs."
msgstr ""
#: demo.module:205
msgid "Snapshot %title has been deleted."
msgstr ""
#: demo.module:213
msgid "File name"
msgstr ""
#: demo.module:218
msgid "Enter the snapshot file name without file extension. Allowed characters are a-z, 0-9, dashes (\"-\"), underscores (\"_\") and dots."
msgstr ""
#: demo.module:221
msgid "Description"
msgstr ""
#: demo.module:224
msgid "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."
msgstr ""
#: demo.module:226
msgid "Are you sure you want to create a new snapshot?"
msgstr ""
#: demo.module:226
msgid "If the above filename already exists, creating a new snapshot will overwrite the existing snapshot. This action cannot be undone."
msgstr ""
#: demo.module:226
msgid "Create"
msgstr ""
#: demo.module:226;264
msgid "Cancel"
msgstr ""
#: demo.module:264
msgid "Are you sure you want to reset the site?"
msgstr ""
#: demo.module:264
msgid "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>"
msgstr ""
#: demo.module:264
msgid "Reset"
msgstr ""
#: demo.module:291
msgid "Active snapshot: !snapshot"
msgstr ""
#: demo.module:295
msgid "Reset now"
msgstr ""
#: demo.module:340
msgid "Successfully restored database from %filename."
msgstr ""
#: demo.module:343
msgid "Failed restoring database from %filename."
msgstr ""
#: demo.module:354
msgid "Unable to open dump file %filename."
msgstr ""
#: demo.module:415
msgid "Snapshot"
msgstr ""
#: demo.module:440
msgid "Modules: "
msgstr ""
#: demo.module:483
msgid "Dump filename %title must contain alphanumeric characters, dots, dashes and underscores only. Other characters, including blanks (spaces), are not allowed."
msgstr ""
#: demo.module:348;358;0
msgid "demo"
msgstr ""
#: demo.module:27
msgid "administer demo settings"
msgstr ""

View File

@@ -0,0 +1,236 @@
# $Id: it.po,v 1.2 2008/03/27 18:58:03 smk Exp $
#
# Italian translation of Drupal (general)
# Copyright YEAR NAME <EMAIL@ADDRESS>
# Generated from files:
# database_pgsql_dump.inc,v 1.1.2.2 2007/09/13 20:30:45 smk
# demo.module,v 1.1.2.15 2007/09/24 16:56:32 smk
# demo.info,v 1.1.2.4 2007/09/13 19:09:32 smk
#
#, fuzzy
msgid ""
""
msgstr "Project-Id-Version: PROJECT VERSION\n"
"POT-Creation-Date: 2005-11-17 15:59+0100\n"
"PO-Revision-Date: 2005-11-17 15:59+0100\n"
"Last-Translator: TheClue <theclue@reloadmagazine.net>\n"
"Language-Team: Italian <theclue@reloadmagazine.net>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: database_pgsql_dump.inc:11
msgid "PostgreSQL support not implemented yet."
msgstr "Supporto per PostgreSQL non ancora implementato."
#: demo.module:41
msgid "Demonstration site"
msgstr "Sito di dimostrazione"
#: demo.module:42
msgid "Administer reset interval, create new dumps and manually reset this site."
msgstr "Amministra l'intervallo di inizializzazione, crea nuove immagini ed "
"inizializza manualmente il sito."
#: demo.module:49
msgid "Status"
msgstr "Stato"
#: demo.module:55
msgid "Manage snapshots"
msgstr "Gestione istantanee"
#: demo.module:64
msgid "Create snapshot"
msgstr "Crea istantanea"
#: demo.module:73
msgid "Reset site"
msgstr "Inizializza sito"
#: demo.module:82
msgid "Demo Site autocomplete"
msgstr "Autocompletamento sito dimostrativo"
#: demo.module:96
msgid "Demo site reset"
msgstr "Inizializzazione sito dimostrativo"
#: demo.module:105
msgid "Reset demo"
msgstr "Inizializzazione demo"
#: demo.module:124
msgid "Never"
msgstr "Mai"
#: demo.module:127
msgid "<p><strong>Last reset:</strong> !date</p>"
msgstr "<p><strong>Ultima inizializzazione:</strong> !date</p>"
#: demo.module:130
msgid "<p><strong>Default snapshot:</strong> !snapshot</p>"
msgstr "<p><strong>Istantanea di default:</strong> !snapshot</p>"
#: demo.module:130
msgid "None"
msgstr "Nessuna"
#: demo.module:137
msgid "Dump settings"
msgstr "Impostazioni immagini sito"
#: demo.module:142
msgid "disabled"
msgstr "disabilitato"
#: demo.module:145
msgid "Automatically reset site every"
msgstr "Inizializza sito automaticamente ogni"
#: demo.module:148
msgid "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."
msgstr "Selezionare quanto spesso il sito dimostrativo è automaticamente inizializzato. Assicurati di aver scelto una istantanea per gli eventi cron in <a href=\"!manage\">Gestione istantanee</a> prima di continuare. <strong>Nota:</strong> Richiede almeno una esecuzione di eventi cron in questo intervallo."
#: demo.module:153
msgid "Dump path"
msgstr "Percorso salvataggio immagini"
#: demo.module:156
msgid "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.<br /><br /><strong>Note: For security reasons you should store site dumps outside of the document root of your webspace!</strong>"
msgstr "Inserisci una directory scrivibile dove il file immagine verrà salvato, ad esempio %files. Il percorso del sito (al "
"momento %confpath) è automaticamente prefisso.<br "
"/><br /><strong>Nota: Per ragioni di sicurezza dovresti salvare i file immagine "
"fuori dalla document root!</strong>"
#: demo.module:160
msgid "Save"
msgstr "Salva"
#: demo.module:168
msgid "Dump could not be created. The directory %directory has not been properly configured."
msgstr "L'immagine non può essere creata. La directory %directory non è stata "
"adeguatamente configurata."
#: demo.module:179
msgid "Available snapshots"
msgstr "Istantanee disponibili"
#: demo.module:184
msgid "Set as default snapshot for cron"
msgstr "Seleziona come istantanea predefinita per eventi cron"
#: demo.module:188
msgid "Delete selected snapshot"
msgstr "Cancella istantanea selezionata"
#: demo.module:198
msgid "Snapshot %title will be used for upcoming cron runs."
msgstr "L'istantanea %title verrà utilizzata per i prossimi eventi cron."
#: demo.module:206
msgid "Snapshot %title has been deleted."
msgstr "L'istantanea %title è stata eliminata."
#: demo.module:214
msgid "File name"
msgstr "Nome file"
#: demo.module:219
msgid "Enter the snapshot file name without file extension. Allowed characters are a-z, 0-9, dashes (\"-\"), underscores (\"_\") and dots."
msgstr "Inserisci il nome del file dell'istantanea senza estensione. Caratteri ammessi sono a-z, 0-9, trattini (\"-\"), underscore (\"_\") e punti."
#: demo.module:222
msgid "Description"
msgstr "Descrizione"
#: demo.module:225
msgid "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."
msgstr "Inserisci eventualmente una descrizione per l'istantanea. Se non "
"verrà fornita una descrizione ed una istantanea con lo stesso nome è "
"già esistente, verrà preservata la precedente descrizione."
#: demo.module:227
msgid "Are you sure you want to create a new snapshot?"
msgstr "Sei sicuro di voler creare una istantanea?"
#: demo.module:227
msgid "If the above filename already exists, creating a new snapshot will overwrite the existing snapshot. This action cannot be undone."
msgstr "Se il file esiste già, la nuova istantanea "
"sovrascriverà quella precedente. L'operazione non può essere "
"annullata."
#: demo.module:227
msgid "Create"
msgstr "Crea"
#: demo.module:227
msgid "Cancel"
msgstr "Cancella"
#: demo.module:265
msgid "Are you sure you want to reset the site?"
msgstr "Sei sicuro di voler inizializzare il sito?"
#: demo.module:265
msgid "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>"
msgstr "L'inizializzazione del sito sovrascriverà tutti i cambiamenti effettuati su questa istallazione di Drupal dopo l'istantanea selezionata.<br /><br /><div style=\"color: red; font-weight: bold; font-size: 18px;\"><center>L'OPERAZIONE NON PUÒ ESSERE ANNULLATA!</center><br /></div>"
#: demo.module:265
msgid "Reset"
msgstr "Inizializza"
#: demo.module:292
msgid "Active snapshot: !snapshot"
msgstr "Istantanea attiva: !snapshot"
#: demo.module:296
msgid "Reset now"
msgstr "Inizializza adesso"
#: demo.module:340
msgid "Succesfully restored database from %filename."
msgstr "Database riportato allo stadio di %filename con successo."
#: demo.module:343
msgid "Failed restoring database from %filename."
msgstr "Impossibile riportare lo stato del database come imposto da %filename"
#: demo.module:354
msgid "Unable to open dump file %filename."
msgstr "Impossibile aprire l'immagine %filename."
#: demo.module:415
msgid "Snapshot"
msgstr "Istantanea"
#: demo.module:440
msgid "Modules: "
msgstr "Moduli:"
#: demo.module:483
msgid "Dump filename %title must contain alphanumeric characters, dots, dashes and underscores only. Other characters, including blanks (spaces), are not allowed."
msgstr "Il nome del file immagine %title deve contenere solo caratteri "
"alfanumerici, punti, trattini e underscore. Differenti caratteri, "
"compresi gli spazi, non sono consentiti."
#: demo.module:348
msgid "demo"
msgstr "sito dimostrativo"
#: demo.module:28
msgid "administer demo settings"
msgstr "amministra settaggi sito dimostrativo"
#: demo.info:0
msgid "Demo Site"
msgstr "Sito dimostrativo"
#: demo.info:0
msgid "Create snapshots and reset the site for demonstration or testing purposes."
msgstr "Crea istantanee ed inizializza il sito per dimostrazioni o a scopi di "
"test."
#: demo.info:0
msgid "Development"
msgstr "Sviluppo"