Skip to content
Commits on Source (3601)
# Drupal editor configuration normalization
# @see http://editorconfig.org/
# This is the top-most .editorconfig file; do not search in parent directories.
root = true
# All files.
[*]
end_of_line = LF
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
# Ignore configuration files that may contain sensitive information.
sites/*/settings*.php
# Ignore paths that contain user-generated content.
sites/*/files
sites/*/private
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# #
# Protect files and directories from prying eyes. # Protect files and directories from prying eyes.
<FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(\..*|Entries.*|Repository|Root|Tag|Template)$"> <FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\..*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock))$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig\.save)$">
Order allow,deny Order allow,deny
</FilesMatch> </FilesMatch>
...@@ -16,17 +16,11 @@ Options +FollowSymLinks ...@@ -16,17 +16,11 @@ Options +FollowSymLinks
# Make Drupal handle any 404 errors. # Make Drupal handle any 404 errors.
ErrorDocument 404 /index.php ErrorDocument 404 /index.php
# Force simple error message for requests for non-existent favicon.ico.
<Files favicon.ico>
# There is no end quote below, for compatibility with Apache 1.3.
ErrorDocument 404 "The requested file favicon.ico was not found.
</Files>
# Set the default handler. # Set the default handler.
DirectoryIndex index.php index.html index.htm DirectoryIndex index.php index.html index.htm
# Override PHP settings that cannot be changed at runtime. See # Override PHP settings that cannot be changed at runtime. See
# sites/default/default.settings.php and drupal_initialize_variables() in # sites/default/default.settings.php and drupal_environment_initialize() in
# includes/bootstrap.inc for settings that can be changed at runtime. # includes/bootstrap.inc for settings that can be changed at runtime.
# PHP 5, Apache 1 and 2. # PHP 5, Apache 1 and 2.
...@@ -62,6 +56,17 @@ DirectoryIndex index.php index.html index.htm ...@@ -62,6 +56,17 @@ DirectoryIndex index.php index.html index.htm
<IfModule mod_rewrite.c> <IfModule mod_rewrite.c>
RewriteEngine on RewriteEngine on
# Set "protossl" to "s" if we were accessed via https://. This is used later
# if you enable "www." stripping or enforcement, in order to ensure that
# you don't bounce between http and https.
RewriteRule ^ - [E=protossl]
RewriteCond %{HTTPS} on
RewriteRule ^ - [E=protossl:s]
# Make sure Authorization HTTP header is available to PHP
# even when running as CGI or FastCGI.
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Block access to "hidden" directories whose names begin with a period. This # Block access to "hidden" directories whose names begin with a period. This
# includes directories used by version control systems such as Subversion or # includes directories used by version control systems such as Subversion or
# Git to store control files. Files whose names begin with a period, as well # Git to store control files. Files whose names begin with a period, as well
...@@ -84,14 +89,15 @@ DirectoryIndex index.php index.html index.htm ...@@ -84,14 +89,15 @@ DirectoryIndex index.php index.html index.htm
# To redirect all users to access the site WITH the 'www.' prefix, # To redirect all users to access the site WITH the 'www.' prefix,
# (http://example.com/... will be redirected to http://www.example.com/...) # (http://example.com/... will be redirected to http://www.example.com/...)
# uncomment the following: # uncomment the following:
# RewriteCond %{HTTP_HOST} .
# RewriteCond %{HTTP_HOST} !^www\. [NC] # RewriteCond %{HTTP_HOST} !^www\. [NC]
# RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301] # RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# #
# To redirect all users to access the site WITHOUT the 'www.' prefix, # To redirect all users to access the site WITHOUT the 'www.' prefix,
# (http://www.example.com/... will be redirected to http://example.com/...) # (http://www.example.com/... will be redirected to http://example.com/...)
# uncomment the following: # uncomment the following:
# RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] # RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
# RewriteRule ^ http://%1%{REQUEST_URI} [L,R=301] # RewriteRule ^ http%{ENV:protossl}://%1%{REQUEST_URI} [L,R=301]
# Modify the RewriteBase if you are using Drupal in a subdirectory or in a # Modify the RewriteBase if you are using Drupal in a subdirectory or in a
# VirtualDocumentRoot and the rewrite rules are not working properly. # VirtualDocumentRoot and the rewrite rules are not working properly.
...@@ -109,6 +115,35 @@ DirectoryIndex index.php index.html index.htm ...@@ -109,6 +115,35 @@ DirectoryIndex index.php index.html index.htm
RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^ index.php [L] RewriteRule ^ index.php [L]
# Rules to correctly serve gzip compressed CSS and JS files.
# Requires both mod_rewrite and mod_headers to be enabled.
<IfModule mod_headers.c>
# Serve gzip compressed CSS files if they exist and the client accepts gzip.
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.css $1\.css\.gz [QSA]
# Serve gzip compressed JS files if they exist and the client accepts gzip.
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.js $1\.js\.gz [QSA]
# Serve correct content types, and prevent mod_deflate double gzip.
RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1]
RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1]
<FilesMatch "(\.js\.gz|\.css\.gz)$">
# Serve correct encoding type.
Header set Content-Encoding gzip
# Force proxies to cache gzipped & non-gzipped css/js files separately.
Header append Vary Accept-Encoding
</FilesMatch>
</IfModule>
</IfModule> </IfModule>
# $Id$ # Add headers to all responses.
<IfModule mod_headers.c>
# Disable content sniffing, since it's an attack vector.
Header always set X-Content-Type-Options nosniff
</IfModule>
This diff is collapsed.
// $Id$ All Drupal code is Copyright 2001 - 2013 by the original authors.
All Drupal code is Copyright 2001 - 2010 by the original authors.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation. the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
...@@ -21,5 +20,25 @@ Drupal includes works under other copyright notices and distributed ...@@ -21,5 +20,25 @@ Drupal includes works under other copyright notices and distributed
according to the terms of the GNU General Public License or a compatible according to the terms of the GNU General Public License or a compatible
license, including: license, including:
jQuery - Copyright (c) 2008 - 2009 John Resig Javascript
Farbtastic - Copyright (c) 2010 Matt Farina
jQuery - Copyright (c) 2010 John Resig
jQuery BBQ - Copyright (c) 2010 "Cowboy" Ben Alman
jQuery Cookie - Copyright (c) 2006 Klaus Hartl
jQuery Form - Copyright (c) 2010 Mike Alsup
jQuery Once - Copyright (c) 2009 Konstantin K�fer
jQuery UI - Copyright (c) 2010 by the original authors
(http://jqueryui.com/about)
Sizzle.js - Copyright (c) 2010 The Dojo Foundation (http://sizzlejs.com/)
PHP
ArchiveTar - Copyright (c) 1997 - 2008 Vincent Blavet
// $Id$
CREATE THE MySQL DATABASE CREATE THE MySQL DATABASE
-------------------------- --------------------------
This step is only necessary if you don't already have a database set-up (e.g. by This step is only necessary if you don't already have a database set up (e.g.,
your host). In the following examples, 'username' is an example MySQL user which by your host). In the following examples, 'username' is an example MySQL user
has the CREATE and GRANT privileges. Use the appropriate user name for your which has the CREATE and GRANT privileges. Use the appropriate user name for
system. your system.
First, you must create a new database for your Drupal site (here, 'databasename' First, you must create a new database for your Drupal site (here, 'databasename'
is the name of the new database): is the name of the new database):
...@@ -19,20 +18,23 @@ initial database files. Next you must log in and set the access database rights: ...@@ -19,20 +18,23 @@ initial database files. Next you must log in and set the access database rights:
mysql -u username -p mysql -u username -p
Again, you will be asked for the 'username' database password. At the MySQL Again, you will be asked for the 'username' database password. At the MySQL
prompt, enter following command: prompt, enter the following command:
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER,
ON databasename.* CREATE TEMPORARY TABLES ON databasename.*
TO 'username'@'localhost' IDENTIFIED BY 'password'; TO 'username'@'localhost' IDENTIFIED BY 'password';
where where:
'databasename' is the name of your database 'databasename' is the name of your database
'username@localhost' is the username of your MySQL account 'username' is the username of your MySQL account
'localhost' is the web server host where Drupal is installed
'password' is the password required for that username 'password' is the password required for that username
Note: Unless your database user has all of the privileges listed above, you will Note: Unless the database user/host combination for your Drupal installation
not be able to run Drupal. has all of the privileges listed above (except possibly CREATE TEMPORARY TABLES,
which is currently only used by Drupal core automated tests and some
contributed modules), you will not be able to install or run Drupal.
If successful, MySQL will reply with: If successful, MySQL will reply with:
......
// $Id$
CREATE THE PostgreSQL DATABASE CREATE THE PostgreSQL DATABASE
------------------------------ ------------------------------
...@@ -7,38 +6,39 @@ Note that the database must be created with UTF-8 (Unicode) encoding. ...@@ -7,38 +6,39 @@ Note that the database must be created with UTF-8 (Unicode) encoding.
1. CREATE DATABASE USER 1. CREATE DATABASE USER
This step is only necessary if you don't already have a user set up (e.g. This step is only necessary if you don't already have a user set up (e.g., by
by your host) or you want to create new user for use with Drupal only. The your host), or want to create a new user for use with Drupal only. The
following command creates a new user named "username" and asks for a following command creates a new user named 'username' and asks for a password
password for that user: for that user:
createuser --pwprompt --encrypted --no-createrole --no-createdb username createuser --pwprompt --encrypted --no-createrole --no-createdb username
If there are no errors then the command was successful If there are no errors, then the command was successful.
2. CREATE THE DRUPAL DATABASE 2. CREATE DRUPAL DATABASE
This step is only necessary if you don't already have a database set up (e.g. This step is only necessary if you don't already have a database set up
by your host) or you want to create new database for use with Drupal only. (e.g., by your host) or want to create a new database for use with Drupal
The following command creates a new database named "databasename", which is only. The following command creates a new database named 'databasename',
owned by previously created "username": which is owned by the previously created 'username':
createdb --encoding=UTF8 --owner=username databasename createdb --encoding=UTF8 --owner=username databasename
If there are no errors then the command was successful If there are no errors, then the command was successful.
3. CREATE A SCHEMA OR SCHEMAS (Optional advanced) 3. CREATE SCHEMA OR SCHEMAS (Optional advanced step)
Drupal will run across different schemas within your database if you so wish. Drupal will run across different schemas within your database if you so wish.
By default, Drupal runs inside the 'public' schema but you can use $db_prefix By default, Drupal runs inside the 'public' schema but you can use $db_prefix
inside settings.php to define a schema for Drupal to inside of or specify tables inside settings.php to define a schema for Drupal to run inside of, or
that are shared inside of a separate schema. Drupal will not create schemas for specify tables that are shared inside of a separate schema. Drupal will not
you, infact the user that Drupal runs as should not be allowed to. You'll need create schemas for you. In fact, the user that Drupal runs as should not be
execute the SQL below as a superuser (such as a postgres user) and replace allowed to do this. You'll need to execute the SQL below as a superuser,
'drupaluser' with the username that Drupal uses to connect to PostgreSQL with replace 'username' with the username that Drupal uses to connect to
and replace schema_name with a schema name you wish to use such as 'shared': PostgreSQL, and replace 'schema_name' with a schema name you wish to use,
such as 'shared':
CREATE SCHEMA schema_name AUTHORIZATION drupaluser; CREATE SCHEMA schema_name AUTHORIZATION username;
Do this for as many schemas as you need. See default.settings.php for how to Do this for as many schemas as you need. See default.settings.php for
set which tables use which schemas. instructions on how to set which tables use which schemas.
// $Id$
SQLITE REQUIREMENTS SQLITE REQUIREMENTS
------------------- -------------------
To use SQLite with your Drupal installation, the following requirements must To use SQLite with your Drupal installation, the following requirements must be
be met: server has PHP 5.2 or later with PDO, and the PDO SQLite driver must met: Server has PHP 5.2 or later with PDO, and the PDO SQLite driver must be
be enabled. enabled.
SQLITE DATABASE CREATION SQLITE DATABASE CREATION
------------------------ ------------------------
The Drupal installer will create the SQLite database for you. The only The Drupal installer will create the SQLite database for you. The only
requirement is the installer must have write permissions the directory where requirement is that the installer must have write permissions to the directory
the database file resides. where the database file resides. This directory (not just the database file) also
has to remain writeable by the web server going forward for SQLite to continue to
be able to operate.
On the "Database configuration" form in the "Database name" field, you must On the "Database configuration" form in the "Database file" field, you must
supply the exact path to where you wish your database file to reside. It is supply the exact path to where you wish your database file to reside. It is
strongly suggested that you choose a path that is outside of the webroot, yet strongly suggested that you choose a path that is outside of the webroot, yet
ensure that the directory is writeable by the web server. ensure that the directory is writeable by the web server.
If you must place your database file in your webroot, you could try using the If you must place your database file in your webroot, you could try using the
following in your "Database name" field: following in your "Database file" field:
sites/default/files/.ht.sqlite sites/default/files/.ht.sqlite
...@@ -28,7 +29,3 @@ Note: The .ht in the name will tell Apache to prevent the database from being ...@@ -28,7 +29,3 @@ Note: The .ht in the name will tell Apache to prevent the database from being
downloaded. Please check that the file is, indeed, protected by your webserver. downloaded. Please check that the file is, indeed, protected by your webserver.
If not, please consult the documentation of your webserver on how to protect a If not, please consult the documentation of your webserver on how to protect a
file from downloading. file from downloading.
USERNAME, PASSWORD, and ADVANCED OPTIONS
----------------------------------------
No username, password, or advanced options are necessary and should not be used.
This diff is collapsed.
// $Id$
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 2, June 1991 Version 2, June 1991
......
// $Id$
Drupal core is maintained by the community. To participate, go to
http://drupal.org/contribute
The people listed here have agreed to do more quality assurance work for
particular areas of Drupal. All of them are subject to change.
Drupal core is built and maintained by the Drupal project community. Everyone is
encouraged to submit issues and changes (patches) to improve Drupal, and to
contribute in other ways -- see https://www.drupal.org/contribute to find out
how.
Branch maintainers Branch maintainers
------------------ ------------------
Drupal 7 The Drupal Core branch maintainers oversee the development of Drupal as a whole.
- Dries Buytaert 'dries' <http://drupal.org/user/1> The branch maintainers for Drupal 7 are:
- Angela Byron 'webchick' <http://drupal.org/user/24967>
- Dries Buytaert 'dries' https://www.drupal.org/u/dries
- Angela Byron 'webchick' https://www.drupal.org/u/webchick
- Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx
- David Rothstein 'David_Rothstein' https://www.drupal.org/u/david_rothstein
- Stefan Ruijsenaars 'stefan.r' https://www.drupal.org/u/stefanr-0
Component maintainers Component maintainers
--------------------- ---------------------
AJAX system The Drupal Core component maintainers oversee the development of Drupal
- Alex Bronstein 'effulgentsia' <http://drupal.org/user/78040> subsystems. See https://www.drupal.org/contribute/core-maintainers for more
- Randy Fay 'rfay' <http://drupal.org/user/30906> information on their responsibilities, and to find out how to become a component
- Earl Miles 'merlinofchaos' <http://drupal.org/user/26979> maintainer. Current component maintainers for Drupal 7:
Ajax system
- Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
- Earl Miles 'merlinofchaos' https://www.drupal.org/u/merlinofchaos
Base system Base system
- Károly Négyesi 'chx' <http://drupal.org/user/9446> - Damien Tournoud 'DamZ' https://www.drupal.org/u/damien-tournoud
- Damien Tournoud 'DamZ' <http://drupal.org/user/22211> - Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
- Moshe Weitzman 'moshe weitzman' <http://drupal.org/user/23>
Batch system Batch system
- Yves Chedemois 'yched' <http://drupal.org/user/39567> - Yves Chedemois 'yched' https://www.drupal.org/u/yched
Cache system
- Damien Tournoud 'DamZ' https://www.drupal.org/u/damien-tournoud
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
Cron system Cron system
- Károly Négyesi 'chx' <http://drupal.org/user/9446> - Derek Wright 'dww' https://www.drupal.org/u/dww
- Derek Wright 'dww' <http://drupal.org/user/46549>
Database system Database system
- Larry Garfield 'Crell' <http://drupal.org/user/26398> - Larry Garfield 'Crell' https://www.drupal.org/u/crell
- MySQL driver - MySQL driver
- Larry Garfield 'Crell' <http://drupal.org/user/26398> - Larry Garfield 'Crell' https://www.drupal.org/u/crell
- David Strauss 'David Strauss' <hhttp://drupal.org/user/93254> - David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss
- PostgreSQL driver - PostgreSQL driver
- Damien Tournoud 'DamZ' <http://drupal.org/user/22211> - Damien Tournoud 'DamZ' https://www.drupal.org/u/damien-tournoud
- Josh Waihi 'fiasco' <http://drupal.org/user/188162> - Josh Waihi 'fiasco' https://www.drupal.org/u/josh-waihi
- Sqlite driver - Sqlite driver
- Damien Tournoud 'DamZ' <http://drupal.org/user/22211> - Damien Tournoud 'DamZ' https://www.drupal.org/u/damien-tournoud
- Károly Négyesi 'chx' <http://drupal.org/user/9446>
Database update system
- Ashok Modi 'BTMash' https://www.drupal.org/u/btmash
Entity system Entity system
- Nathaniel Catchpole 'catch' <http://drupal.org/user/35733> - Wolfgang Ziegler 'fago' https://www.drupal.org/u/fago
- Franz Heinzmann 'Frando' <http://drupal.org/user/21850> - Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
- Franz Heinzmann 'Frando' https://www.drupal.org/u/frando
File system File system
- Andrew Morton 'drewish' <http://drupal.org/user/34869> - Andrew Morton 'drewish' https://www.drupal.org/u/drewish
- Aaron Winborn 'aaron' <http://drupal.org/user/33420> - Aaron Winborn 'aaron' https://www.drupal.org/u/aaron
Form system Form system
- Károly Négyesi 'chx' <http://drupal.org/user/9446> - Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
- Alex Bronstein 'effulgentsia' <http://drupal.org/user/78040> - Wolfgang Ziegler 'fago' https://www.drupal.org/u/fago
- Wolfgang Ziegler 'fago' <http://drupal.org/user/16747> - Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
- Daniel F. Kudwien 'sun' <http://drupal.org/user/54136> - Franz Heinzmann 'Frando' https://www.drupal.org/u/frando
- Franz Heinzmann 'Frando' <http://drupal.org/user/21850>
Image system Image system
- Andrew Morton 'drewish' <http://drupal.org/user/34869> - Andrew Morton 'drewish' https://www.drupal.org/u/drewish
- Nathan Haug 'quicksketch' <http://drupal.org/user/35821> - Nathan Haug 'quicksketch' https://www.drupal.org/u/quicksketch
Install system Install system
- David Rothstein 'David_Rothstein' <http://drupal.org/user/124982> - David Rothstein 'David_Rothstein' https://www.drupal.org/u/david_rothstein
JavaScript JavaScript
- ? - Théodore Biadala 'nod_' https://www.drupal.org/u/nod_
- Steve De Jonghe 'seutje' https://www.drupal.org/u/seutje
Language system Language system
- Francesco Placella 'plach' <http://drupal.org/user/183211> - Francesco Placella 'plach' https://www.drupal.org/u/plach
- Daniel F. Kudwien 'sun' <http://drupal.org/user/54136> - Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
Lock system Lock system
- Damien Tournoud 'DamZ' <http://drupal.org/user/22211> - Damien Tournoud 'DamZ' https://www.drupal.org/u/damien-tournoud
Mail system Mail system
- ? - ?
Markup Markup
- Jacine Rodriguez 'Jacine' <http://drupal.org/user/88931> - Jacine Luisi 'Jacine' https://www.drupal.org/u/jacine
- Daniel F. Kudwien 'sun' <http://drupal.org/user/54136> - Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
Menu system Menu system
- Peter Wolanin 'pwolanin' <http://drupal.org/user/49851> - Peter Wolanin 'pwolanin' https://www.drupal.org/u/pwolanin
- Károly Négyesi 'chx' <http://drupal.org/user/9446>
Path system Path system
- Dave Reid 'davereid' <http://drupal.org/user/53892> - Dave Reid 'davereid' https://www.drupal.org/u/dave-reid
- Nathaniel Catchpole 'catch' <http://drupal.org/user/35733> - Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
Render system Render system
- Moshe Weitzman 'moshe weitzman' <http://drupal.org/user/23> - Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
- Alex Bronstein 'effulgentsia' <http://drupal.org/user/78040> - Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
- Franz Heinzmann 'Frando' <http://drupal.org/user/21850> - Franz Heinzmann 'Frando' https://www.drupal.org/u/frando
Theme system Theme system
- Earl Miles 'merlinofchaos' <http://drupal.org/user/26979> - Earl Miles 'merlinofchaos' https://www.drupal.org/u/merlinofchaos
- Alex Bronstein 'effulgentsia' <http://drupal.org/user/78040> - Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
- Joon Park 'dvessel' <http://drupal.org/user/56782> - Joon Park 'dvessel' https://www.drupal.org/u/dvessel
- John Albin Wilkins 'JohnAlbin' https://www.drupal.org/u/johnalbin
Token system Token system
- Dave Reid 'davereid' <http://drupal.org/user/53892> - Dave Reid 'davereid' https://www.drupal.org/u/dave-reid
Update system
- ?
XML-RPC system XML-RPC system
- ? - Frederic G. Marand 'fgm' https://www.drupal.org/u/fgm
Topic coordinators Topic coordinators
------------------ ------------------
Accessibility Accessibility
- Everett Zufelt 'Everett Zufelt' <http://drupal.org/user/406552> - Everett Zufelt 'Everett Zufelt' https://www.drupal.org/u/everett-zufelt
- Brandon Bowersox-Johnson 'bowersox' https://www.drupal.org/u/bowersox
Documentation Documentation
- Addison Berry 'add1sun' <http://drupal.org/user/65088> - Jennifer Hodgdon 'jhodgdon' https://www.drupal.org/u/jhodgdon
- Jennifer Hodgdon 'jhodgdon' <http://drupal.org/user/155601>
Security
- Heine Deelstra 'Heine' <http://drupal.org/user/17943>
Translations Translations
- Gerhard Killesreiter 'killes' <http://drupal.org/user/83> - Gerhard Killesreiter 'killes' https://www.drupal.org/u/gerhard-killesreiter
User experience and usability User experience and usability
- Roy Scholten 'yoroy' <http://drupal.org/user/41502> - Roy Scholten 'yoroy' https://www.drupal.org/u/yoroy
- Bojhan Somers 'Bojhan' <http://drupal.org/user/87969> - Bojhan Somers 'Bojhan' https://www.drupal.org/u/bojhan
Node Access
- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
- Ken Rickard 'agentrickard' https://www.drupal.org/u/agentrickard
Security team
-----------------
To report a security issue, see: https://www.drupal.org/security-team/report-issue
The Drupal security team provides Security Advisories for vulnerabilities,
assists developers in resolving security issues, and provides security
documentation. See https://www.drupal.org/security-team for more information.
The security team lead is:
- Michael Hess 'mlhess' https://www.drupal.org/u/mlhess
Module maintainers Module maintainers
...@@ -146,141 +167,141 @@ Aggregator module ...@@ -146,141 +167,141 @@ Aggregator module
- ? - ?
Block module Block module
- ? - John Albin Wilkins 'JohnAlbin' https://www.drupal.org/u/johnalbin
Blog module Blog module
- ? - ?
Book module Book module
- Peter Wolanin 'pwolanin' <http://drupal.org/user/49851> - Peter Wolanin 'pwolanin' https://www.drupal.org/u/pwolanin
Color module Color module
- ? - ?
Comment module Comment module
- Nathaniel Catchpole 'catch' <http://drupal.org/user/35733> - Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
Contact module Contact module
- Dave Reid 'davereid' <http://drupal.org/user/53892> - Dave Reid 'davereid' https://www.drupal.org/u/dave-reid
Contextual module Contextual module
- Daniel F. Kudwien 'sun' <http://drupal.org/user/54136> - Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
Dashboard module Dashboard module
- ? - ?
Database logging module Database logging module
- Khalid Baheyeldin 'kbahey' <http://drupal.org/user/4063> - Khalid Baheyeldin 'kbahey' https://www.drupal.org/u/kbahey
Field module Field module
- Yves Chedemois 'yched' <http://drupal.org/user/39567> - Yves Chedemois 'yched' https://www.drupal.org/u/yched
- Barry Jaspan 'bjaspan' <http://drupal.org/user/46413> - Barry Jaspan 'bjaspan' https://www.drupal.org/u/bjaspan
Field UI module Field UI module
- Yves Chedemois 'yched' <http://drupal.org/user/39567> - Yves Chedemois 'yched' https://www.drupal.org/u/yched
File module File module
- Aaron Winborn 'aaron' <http://drupal.org/user/33420> - Aaron Winborn 'aaron' https://www.drupal.org/u/aaron
Filter module Filter module
- Daniel F. Kudwien 'sun' <http://drupal.org/user/54136> - Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
Forum module Forum module
- ? - Lee Rowlands 'larowlan' https://www.drupal.org/u/larowlan
Help module Help module
- ? - ?
Image module Image module
- Nathan Haug 'quicksketch' <http://drupal.org/user/35821> - Nathan Haug 'quicksketch' https://www.drupal.org/u/quicksketch
Locale module Locale module
- Gábor Hojtsy 'Gábor Hojtsy' <http://drupal.org/user/4166> - Gábor Hojtsy 'Gábor Hojtsy' https://www.drupal.org/u/gábor-hojtsy
Menu module Menu module
- ? - ?
Node module Node module
- Moshe Weitzman 'moshe weitzman' <http://drupal.org/user/23> - Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
- David Strauss 'David Strauss' <http://drupal.org/user/93254> - David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss
OpenID module OpenID module
- Heine Deelstra 'Heine' <http://drupal.org/user/17943> - Vojtech Kusy 'wojtha' https://www.drupal.org/u/wojtha
- Christian Schmidt 'c960657' <http://drupal.org/user/216078> - Christian Schmidt 'c960657' https://www.drupal.org/u/c960657
- Damien Tournoud 'DamZ' <http://drupal.org/user/22211> - Damien Tournoud 'DamZ' https://www.drupal.org/u/damien-tournoud
Overlay module Overlay module
- Katherine Senzee 'ksenzee' <http://drupal.org/user/139855> - Katherine Senzee 'ksenzee' https://www.drupal.org/u/ksenzee
Path module Path module
- Dave Reid 'davereid' <http://drupal.org/user/53892> - Dave Reid 'davereid' https://www.drupal.org/u/dave-reid
PHP module PHP module
- ? - ?
Poll module Poll module
- ? - Andrei Mateescu 'amateescu' https://www.drupal.org/u/amateescu
Profile module Profile module
- ? - ?
RDF module RDF module
- Stéphane Corlosquet 'scor' <http://drupal.org/user/52142> - Stéphane Corlosquet 'scor' https://www.drupal.org/u/scor
Search module Search module
- Jennifer Hodgdon 'jhodgdon' <http://drupal.org/user/155601> - Doug Green 'douggreen' https://www.drupal.org/u/douggreen
- Doug Green 'douggreen' <http://drupal.org/user/29191>
Shortcut module Shortcut module
- David Rothstein 'David_Rothstein' <http://drupal.org/user/124982> - David Rothstein 'David_Rothstein' https://www.drupal.org/u/david_rothstein
Simpletest module Simpletest module
- Jimmy Berry 'boombatower' <http://drupal.org/user/214218> - Jimmy Berry 'boombatower' https://www.drupal.org/u/boombatower
- Károly Négyesi 'chx' <http://drupal.org/user/9446>
Statistics module Statistics module
- Dave Reid 'davereid' <http://drupal.org/user/53892> - Tim Millwood 'timmillwood' https://www.drupal.org/u/timmillwood
Syslog module Syslog module
- Khalid Baheyeldin 'kbahey' <http://drupal.org/user/4063> - Khalid Baheyeldin 'kbahey' https://www.drupal.org/u/kbahey
System module System module
- ? - ?
Taxonomy module Taxonomy module
- Nathaniel Catchpole 'catch' <http://drupal.org/user/35733> - Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
- Benjamin Doherty 'bangpound' <http://drupal.org/user/100456> - Benjamin Doherty 'bangpound' https://www.drupal.org/u/bangpound
Toolbar module Toolbar module
- ? - ?
Tracker module Tracker module
- David Strauss 'David Strauss' <http://drupal.org/user/93254> - David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss
Translation module Translation module
- Francesco Placella 'plach' <http://drupal.org/user/183211> - Francesco Placella 'plach' https://www.drupal.org/u/plach
Trigger module Trigger module
- ? - ?
Update module Update module
- Derek Wright 'dww' <http://drupal.org/user/46549> - Derek Wright 'dww' https://www.drupal.org/u/dww
- Dave Reid 'davereid' <http://drupal.org/user/53892>
User module User module
- Moshe Weitzman 'moshe weitzman' <http://drupal.org/user/23> - Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
- David Strauss 'David Strauss' <http://drupal.org/user/93254> - David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss
Theme maintainers Theme maintainers
----------------- -----------------
Bartik theme
- Jen Simmons 'jensimmons' https://www.drupal.org/u/jensimmons
- Jeff Burns 'Jeff Burnz' https://www.drupal.org/u/jeff-burnz
Garland theme Garland theme
- Stefan Nagtegaal 'steef' <http://drupal.org/user/612> - John Albin Wilkins 'JohnAlbin' https://www.drupal.org/u/johnalbin
Seven theme Seven theme
- ? - Jeff Burns 'Jeff Burnz' https://www.drupal.org/u/jeff-burnz
Stark theme Stark theme
- John Wilkins 'JohnAlbin' <http://drupal.org/user/32095> - John Albin Wilkins 'JohnAlbin' https://www.drupal.org/u/johnalbin
CONTENTS OF THIS FILE
---------------------
* About Drupal
* Configuration and features
* Installation profiles
* Appearance
* Developing for Drupal
ABOUT DRUPAL
------------
Drupal is an open source content management platform supporting a variety of
websites ranging from personal weblogs to large community-driven websites. For
more information, see the Drupal website at http://drupal.org/, and join the
Drupal community at http://drupal.org/community.
Legal information about Drupal:
* Know your rights when using Drupal:
See LICENSE.txt in the same directory as this document.
* Learn about the Drupal trademark and logo policy:
http://drupal.com/trademark
CONFIGURATION AND FEATURES
--------------------------
Drupal core (what you get when you download and extract a drupal-x.y.tar.gz or
drupal-x.y.zip file from http://drupal.org/project/drupal) has what you need to
get started with your website. It includes several modules (extensions that add
functionality) for common website features, such as managing content, user
accounts, image uploading, and search. Core comes with many options that allow
site-specific configuration. In addition to the core modules, there are
thousands of contributed modules (for functionality not included with Drupal
core) available for download.
More about configuration:
* Install, upgrade, and maintain Drupal:
See INSTALL.txt and UPGRADE.txt in the same directory as this document.
* Learn about how to use Drupal to create your site:
http://drupal.org/documentation
* Download contributed modules to sites/all/modules to extend Drupal's
functionality:
http://drupal.org/project/modules
* See also: "Developing for Drupal" for writing your own modules, below.
INSTALLATION PROFILES
---------------------
Installation profiles define additional steps (such as enabling modules,
defining content types, etc.) that run after the base installation provided
by core when Drupal is first installed. There are two basic installation
profiles provided with Drupal core.
Installation profiles from the Drupal community modify the installation process
to provide a website for a specific use case, such as a CMS for media
publishers, a web-based project tracking tool, or a full-fledged CRM for
non-profit organizations raising money and accepting donations. They can be
distributed as bare installation profiles or as "distributions". Distributions
include Drupal core, the installation profile, and all other required
extensions, such as contributed and custom modules, themes, and third-party
libraries. Bare installation profiles require you to download Drupal Core and
the required extensions separately; place the downloaded profile in the
/profiles directory before you start the installation process. Note that the
contents of this directory may be overwritten during updates of Drupal core;
it is advised to keep code backups or use a version control system.
Additionally, modules and themes may be placed inside subdirectories in a
specific installation profile such as profiles/your_site_profile/modules and
profiles/your_site_profile/themes respectively to restrict their usage to only
sites that were installed with that specific profile.
More about installation profiles and distributions:
* Read about the difference between installation profiles and distributions:
http://drupal.org/node/1089736
* Download contributed installation profiles and distributions:
http://drupal.org/project/distributions
* Develop your own installation profile or distribution:
http://drupal.org/developing/distributions
APPEARANCE
----------
In Drupal, the appearance of your site is set by the theme (themes are
extensions that set fonts, colors, and layout). Drupal core comes with several
themes. More themes are available for download, and you can also create your own
custom theme.
More about themes:
* Download contributed themes to sites/all/themes to modify Drupal's
appearance:
http://drupal.org/project/themes
* Develop your own theme:
http://drupal.org/documentation/theme
DEVELOPING FOR DRUPAL
---------------------
Drupal contains an extensive API that allows you to add to and modify the
functionality of your site. The API consists of "hooks", which allow modules to
react to system events and customize Drupal's behavior, and functions that
standardize common operations such as database queries and form generation. The
flexible hook architecture means that you should never need to directly modify
the files that come with Drupal core to achieve the functionality you want;
instead, functionality modifications take the form of modules.
When you need new functionality for your Drupal site, search for existing
contributed modules. If you find a module that matches except for a bug or an
additional needed feature, change the module and contribute your improvements
back to the project in the form of a "patch". Create new custom modules only
when nothing existing comes close to what you need.
More about developing:
* Search for existing contributed modules:
http://drupal.org/project/modules
* Contribute a patch:
http://drupal.org/patch/submit
* Develop your own module:
http://drupal.org/developing/modules
* Follow best practices:
http://drupal.org/best-practices
* Refer to the API documentation:
http://api.drupal.org/api/drupal/7
// $Id$ INTRODUCTION
------------
This document describes how to:
UPGRADING * Update your Drupal site from one minor 7.x version to another minor 7.x
--------- version; for example, from 7.8 to 7.9, or from 7.6 to 7.10.
Prior to upgrading, you should ensure that: * Upgrade your Drupal site's major version from 6.x to 7.x.
* Your system meets or exceeds Drupal's minimum requirements as shown at First steps and definitions:
http://drupal.org/requirements.
* You have a backup of all your relevant data (#1).
* Custom and contributed modules have been checked for compatibility (#11).
* Custom and contributed themes have been checked for compatibility (#11).
* You have read through this entire document.
Let's begin! * If you are upgrading to Drupal version x.y, then x is known as the major
version number, and y is known as the minor version number. The download
file will be named drupal-x.y.tar.gz (or drupal-x.y.zip).
1. Back up your Drupal database and site root directory. Be especially sure * All directories mentioned in this document are relative to the directory of
to back up your "sites" directory which contains your configuration file, your Drupal installation.
added modules and themes, and your site's uploaded files. If other files
have modifications, such as .htaccess or robots.txt, back those up as well.
Note: for a single site setup, the configuration file is the "settings.php" * Make a full backup of all files, directories, and your database(s) before
file located at sites/default/settings.php. The default.settings.php file starting, and save it outside your Drupal installation directory.
contains a clean copy for restoration purposes, if required. Instructions may be found at http://drupal.org/upgrade/backing-up-the-db
For multisite configurations, the configuration file is located in a * It is wise to try an update or upgrade on a test copy of your site before
structure like the following: applying it to your live site. Even minor updates can cause your site's
behavior to change.
sites/default/settings.php * Each new release of Drupal has release notes, which explain the changes made
sites/example.com/settings.php since the previous version and any special instructions needed to update or
sites/sub.example.com/settings.php upgrade to the new version. You can find a link to the release notes for the
sites/sub.example.com.path/settings.php version you are upgrading or updating to on the Drupal project page
(http://drupal.org/project/drupal).
More information on multisite configuration is located in INSTALL.txt. UPGRADE PROBLEMS
----------------
If you encounter errors during this process,
2. If possible, log on either as a user with the "Administer software updates" * Note any error messages you see.
permission or as the user with user ID 1, which is the first account
created (also known as the site maintenance account). Only these accounts
will be able to automatically access update.php in step #10. There are
special instructions in step #10 if you are unable to log on as one of
these users. Do not close your browser until the final step is complete.
3. Place the site in "Offline" mode, to let the database updates run without * Restore your site to its previous state, using the file and database backups
interruption and avoid displaying errors to end users of the site. This you created before you started the upgrade process. Do not attempt to do
option is at http://www.example.com/?q=admin/config/development/maintenance further upgrades on a site that had update problems.
(replace www.example.com with your installation's domain name and path).
4. If using a custom or contributed theme, switch to Garland. * Consult one of the support options listed on http://drupal.org/support
5. Disable all custom and contributed modules. This includes any modules that More in-depth information on upgrading can be found at http://drupal.org/upgrade
are not listed under 'Core - required' or 'Core - optional' on
http://www.example.com/?q=admin/build/modules (replace www.example.com with
your installation's domain name and path).
6. Remove all old files and directories from the Drupal installation directory. MINOR VERSION UPDATES
---------------------
To update from one minor 7.x version of Drupal to any later 7.x version, after
following the instructions in the INTRODUCTION section at the top of this file:
7. Unpack the new files and directories into the Drupal installation directory. 1. Log in as a user with the permission "Administer software updates".
8. Copy your backed up "files" and "sites" directories to the Drupal 2. Go to Administration > Configuration > Development > Maintenance mode.
installation directory. If other system files such as .htaccess or Enable the "Put site into maintenance mode" checkbox and save the
robots.txt were customized, re-create the modifications in the new configuration.
versions of the files using the backups taken in step #1.
9. Verify the new configuration file to make sure it has correct information. 3. Remove all old core files and directories, except for the 'sites' directory
and any custom files you added elsewhere.
10. Run update.php by visiting http://www.example.com/update.php (replace If you made modifications to files like .htaccess or robots.txt, you will
www.example.com with your Drupal installation's domain name and path). This need to re-apply them from your backup, after the new files are in place.
step will update the core database tables to the new Drupal installation.
Note: if you are unable to access update.php do the following: Sometimes an update includes changes to default.settings.php (this will be
noted in the release notes). If that's the case, follow these steps:
- Open your settings.php with a text editor. - Locate your settings.php file in the /sites/* directory. (Typically
sites/default.)
- There is a line that says $update_free_access = FALSE; - Make a backup copy of your settings.php file, with a different file name.
Change it to $update_free_access = TRUE;
- Once update.php is done, you must change the settings.php file - Make a copy of the new default.settings.php file, and name the copy
back to its original form with $update_free_access = FALSE; settings.php (overwriting your previous settings.php file).
11. Ensure that the versions of all custom and contributed modules match the - Copy the custom and site-specific entries from the backup you made into the
new Drupal version to which you have updated. For a major update, such as new settings.php file. You will definitely need the lines giving the
from 5.x to 6.x, modules from previous versions will not be compatible database information, and you will also want to copy in any other
and updated versions will be required. customizations you have added.
- For contributed modules, check http://drupal.org/project/modules You can find the release notes for your version at
for the version of a module matching your version of Drupal. https://www.drupal.org/project/drupal. At bottom of the project page under
"Downloads" use the link for your version of Drupal to view the release
notes. If your version is not listed, use the 'View all releases' link. From
this page you can scroll down or use the filter to find your version and its
release notes.
- For custom modules, review http://drupal.org/update/modules to 4. Download the latest Drupal 7.x release from http://drupal.org to a
ensure that a custom module is compatible with the current version. directory outside of your web root. Extract the archive and copy the files
into your Drupal directory.
12. Re-enable custom and contributed modules and re-run update.php On a typical Unix/Linux command line, use the following commands to download
to update custom and contributed database tables. and extract:
13. Return the site to its original theme (if you switched to a core theme in wget http://drupal.org/files/projects/drupal-x.y.tar.gz
step #4). If your site uses a custom or contributed theme, make sure it is tar -zxvf drupal-x.y.tar.gz
compatible with your version of Drupal.
- For contributed themes, check http://drupal.org/project/themes This creates a new directory drupal-x.y/ containing all Drupal files and
for the version of a theme matching your version of Drupal. directories. Copy the files into your Drupal installation directory:
- For custom themes, review http://drupal.org/update/theme to ensure cp -R drupal-x.y/* drupal-x.y/.htaccess /path/to/your/installation
that a custom theme is compatible with the current version.
14. Finally, return your site to "Online" mode so your visitors may resume If you do not have command line access to your server, download the archive
browsing. As in step #3, this option is available in your administration from http://drupal.org using your web browser, extract it, and then use an
screens at http://www.example.com/?q=admin/config/development/maintenance FTP client to upload the files to your web root.
(replace www.example.com with your installation's domain name and path).
For more information on upgrading visit 5. Re-apply any modifications to files such as .htaccess or robots.txt.
the Drupal handbook at http://drupal.org/upgrade
6. Run update.php by visiting http://www.example.com/update.php (replace
www.example.com with your domain name). This will update the core database
tables.
If you are unable to access update.php do the following:
- Open settings.php with a text editor.
- Find the line that says:
$update_free_access = FALSE;
- Change it into:
$update_free_access = TRUE;
- Once the upgrade is done, $update_free_access must be reverted to FALSE.
7. Go to Administration > Reports > Status report. Verify that everything is
working as expected.
8. Ensure that $update_free_access is FALSE in settings.php.
9. Go to Administration > Configuration > Development > Maintenance mode.
Disable the "Put site into maintenance mode" checkbox and save the
configuration.
MAJOR VERSION UPGRADE
---------------------
To upgrade from a previous major version of Drupal to Drupal 7.x, after
following the instructions in the INTRODUCTION section at the top of this file:
1. Check on the Drupal 7 status of your contributed and custom modules and
themes. See http://drupal.org/node/948216 for information on upgrading
contributed modules and themes. See http://drupal.org/node/895314 for a list
of modules that have been moved into core for Drupal 7, and instructions on
how to update them. See http://drupal.org/update/modules for information on
how to update your custom modules, and http://drupal.org/update/theme for
custom themes.
You may decide at this point that you cannot upgrade your site, because
needed modules or themes are not ready for Drupal 7.
2. Update to the latest available version of Drupal 6.x (if your current version
is Drupal 5.x, you have to upgrade to 6.x first). If you need to update,
download Drupal 6.x and follow the instructions in its UPGRADE.txt. This
document only applies for upgrades from 6.x to 7.x.
3. In addition to updating to the latest available version of Drupal 6.x core,
you must also upgrade all of your contributed modules for Drupal to their
latest Drupal 6.x versions.
4. Log in as user ID 1 (the site maintenance user).
5. Go to Administer > Site configuration > Site maintenance. Select
"Off-line" and save the configuration.
6. Go to Administer > Site building > Themes. Enable "Garland" and select it as
the default theme.
7. Go to Administer > Site building > Modules. Disable all modules that are not
listed under "Core - required" or "Core - optional". It is possible that some
modules cannot be disabled, because others depend on them. Repeat this step
until all non-core modules are disabled.
If you know that you will not re-enable some modules for Drupal 7.x and you
no longer need their data, then you can uninstall them under the Uninstall
tab after disabling them.
8. On the command line or in your FTP client, remove the file
sites/default/default.settings.php
9. Remove all old core files and directories, except for the 'sites' directory
and any custom files you added elsewhere.
If you made modifications to files like .htaccess or robots.txt, you will
need to re-apply them from your backup, after the new files are in place.
10. If you uninstalled any modules, remove them from the sites/all/modules and
other sites/*/modules directories. Leave other modules in place, even though
they are incompatible with Drupal 7.x.
11. Download the latest Drupal 7.x release from http://drupal.org to a
directory outside of your web root. Extract the archive and copy the files
into your Drupal directory.
On a typical Unix/Linux command line, use the following commands to download
and extract:
wget http://drupal.org/files/projects/drupal-x.y.tar.gz
tar -zxvf drupal-x.y.tar.gz
This creates a new directory drupal-x.y/ containing all Drupal files and
directories. Copy the files into your Drupal installation directory:
cp -R drupal-x.y/* drupal-x.y/.htaccess /path/to/your/installation
If you do not have command line access to your server, download the archive
from http://drupal.org using your web browser, extract it, and then use an
FTP client to upload the files to your web root.
12. Re-apply any modifications to files such as .htaccess or robots.txt.
13. Make your settings.php file writeable, so that the update process can
convert it to the format of Drupal 7.x. settings.php is usually located in
sites/default/settings.php
14. Run update.php by visiting http://www.example.com/update.php (replace
www.example.com with your domain name). This will update the core database
tables.
If you are unable to access update.php do the following:
- Open settings.php with a text editor.
- Find the line that says:
$update_free_access = FALSE;
- Change it into:
$update_free_access = TRUE;
- Once the upgrade is done, $update_free_access must be reverted to FALSE.
15. Backup your database after the core upgrade has run.
16. Replace and update your non-core modules and themes, following the
procedures at http://drupal.org/node/948216
17. Go to Administration > Reports > Status report. Verify that everything is
working as expected.
18. Ensure that $update_free_access is FALSE in settings.php.
19. Go to Administration > Configuration > Development > Maintenance mode.
Disable the "Put site into maintenance mode" checkbox and save the
configuration.
To get started with Drupal 7 administration, visit
http://drupal.org/getting-started/7/admin
<?php <?php
// $Id$
/** /**
* @file * @file
* Administrative script for running authorized file operations. * Administrative script for running authorized file operations.
* *
* Using this script, the site owner (the user actually owning the files on * Using this script, the site owner (the user actually owning the files on the
* the webserver) can authorize certain file-related operations to proceed * webserver) can authorize certain file-related operations to proceed with
* with elevated privileges, for example to deploy and upgrade modules or * elevated privileges, for example to deploy and upgrade modules or themes.
* themes. Users should not visit this page directly, but instead use an * Users should not visit this page directly, but instead use an administrative
* administrative user interface which knows how to redirect the user to this * user interface which knows how to redirect the user to this script as part of
* script as part of a multistep process. This script actually performs the * a multistep process. This script actually performs the selected operations
* selected operations without loading all of Drupal, to be able to more * without loading all of Drupal, to be able to more gracefully recover from
* gracefully recover from errors. Access to the script is controlled by a * errors. Access to the script is controlled by a global killswitch in
* global killswitch in settings.php ('allow_authorize_operations') and via * settings.php ('allow_authorize_operations') and via the 'administer software
* the 'administer software updates' permission. * updates' permission.
* *
* There are helper functions for setting up an operation to run via this * There are helper functions for setting up an operation to run via this
* system in modules/system/system.module. For more information, see: * system in modules/system/system.module. For more information, see:
...@@ -22,21 +21,22 @@ ...@@ -22,21 +21,22 @@
*/ */
/** /**
* Root directory of Drupal installation. * Defines the root directory of the Drupal installation.
*/ */
define('DRUPAL_ROOT', getcwd()); define('DRUPAL_ROOT', getcwd());
/** /**
* Global flag to identify update.php and authorize.php runs, and so * Global flag to identify update.php and authorize.php runs.
* avoid various unwanted operations, such as hook_init() and *
* hook_exit() invokes, css/js preprocessing and translation, and * Identifies update.php and authorize.php runs, avoiding unwanted operations
* solve some theming issues. This flag is checked on several places * such as hook_init() and hook_exit() invokes, css/js preprocessing and
* in Drupal code (not just authorize.php). * translation, and solves some theming issues. The flag is checked in other
* places in Drupal code (not just authorize.php).
*/ */
define('MAINTENANCE_MODE', 'update'); define('MAINTENANCE_MODE', 'update');
/** /**
* Render a 403 access denied page for authorize.php * Renders a 403 access denied page for authorize.php.
*/ */
function authorize_access_denied_page() { function authorize_access_denied_page() {
drupal_add_http_header('Status', '403 Forbidden'); drupal_add_http_header('Status', '403 Forbidden');
...@@ -46,13 +46,13 @@ function authorize_access_denied_page() { ...@@ -46,13 +46,13 @@ function authorize_access_denied_page() {
} }
/** /**
* Determine if the current user is allowed to run authorize.php. * Determines if the current user is allowed to run authorize.php.
* *
* The killswitch in settings.php overrides all else, otherwise, the user must * The killswitch in settings.php overrides all else, otherwise, the user must
* have access to the 'administer software updates' permission. * have access to the 'administer software updates' permission.
* *
* @return * @return
* TRUE if the current user can run authorize.php, otherwise FALSE. * TRUE if the current user can run authorize.php, and FALSE if not.
*/ */
function authorize_access_allowed() { function authorize_access_allowed() {
return variable_get('allow_authorize_operations', TRUE) && user_access('administer software updates'); return variable_get('allow_authorize_operations', TRUE) && user_access('administer software updates');
...@@ -61,7 +61,6 @@ function authorize_access_allowed() { ...@@ -61,7 +61,6 @@ function authorize_access_allowed() {
// *** Real work of the script begins here. *** // *** Real work of the script begins here. ***
require_once DRUPAL_ROOT . '/includes/bootstrap.inc'; require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
require_once DRUPAL_ROOT . '/includes/session.inc';
require_once DRUPAL_ROOT . '/includes/common.inc'; require_once DRUPAL_ROOT . '/includes/common.inc';
require_once DRUPAL_ROOT . '/includes/file.inc'; require_once DRUPAL_ROOT . '/includes/file.inc';
require_once DRUPAL_ROOT . '/includes/module.inc'; require_once DRUPAL_ROOT . '/includes/module.inc';
...@@ -75,7 +74,7 @@ function authorize_access_allowed() { ...@@ -75,7 +74,7 @@ function authorize_access_allowed() {
global $conf; global $conf;
// We have to enable the user and system modules, even to check access and // We have to enable the user and system modules, even to check access and
// display errors via the maintainence theme. // display errors via the maintenance theme.
$module_list['system']['filename'] = 'modules/system/system.module'; $module_list['system']['filename'] = 'modules/system/system.module';
$module_list['user']['filename'] = 'modules/user/user.module'; $module_list['user']['filename'] = 'modules/user/user.module';
module_list(TRUE, FALSE, FALSE, $module_list); module_list(TRUE, FALSE, FALSE, $module_list);
...@@ -113,7 +112,7 @@ function authorize_access_allowed() { ...@@ -113,7 +112,7 @@ function authorize_access_allowed() {
} }
if (isset($_SESSION['authorize_operation']['page_title'])) { if (isset($_SESSION['authorize_operation']['page_title'])) {
drupal_set_title(check_plain($_SESSION['authorize_operation']['page_title'])); drupal_set_title($_SESSION['authorize_operation']['page_title']);
} }
else { else {
drupal_set_title(t('Authorize file system changes')); drupal_set_title(t('Authorize file system changes'));
...@@ -125,10 +124,10 @@ function authorize_access_allowed() { ...@@ -125,10 +124,10 @@ function authorize_access_allowed() {
// Clear the session out. // Clear the session out.
unset($_SESSION['authorize_results']); unset($_SESSION['authorize_results']);
unset($_SESSION['authorize_operation']); unset($_SESSION['authorize_operation']);
unset($_SESSION['authorize_filetransfer_backends']); unset($_SESSION['authorize_filetransfer_info']);
if (!empty($results['page_title'])) { if (!empty($results['page_title'])) {
drupal_set_title(check_plain($results['page_title'])); drupal_set_title($results['page_title']);
} }
if (!empty($results['page_message'])) { if (!empty($results['page_message'])) {
drupal_set_message($results['page_message']['message'], $results['page_message']['type']); drupal_set_message($results['page_message']['message'], $results['page_message']['type']);
...@@ -140,20 +139,21 @@ function authorize_access_allowed() { ...@@ -140,20 +139,21 @@ function authorize_access_allowed() {
if (is_array($results['tasks'])) { if (is_array($results['tasks'])) {
$links += $results['tasks']; $links += $results['tasks'];
} }
else {
$links = array_merge($links, array(
l(t('Administration pages'), 'admin'),
l(t('Front page'), '<front>'),
));
}
$links = array_merge($links, array( $output .= theme('item_list', array('items' => $links, 'title' => t('Next steps')));
l(t('Administration pages'), 'admin'),
l(t('Front page'), '<front>'),
));
$output .= theme('item_list', array('items' => $links));
} }
// If a batch is running, let it run. // If a batch is running, let it run.
elseif (isset($_GET['batch'])) { elseif (isset($_GET['batch'])) {
$output = _batch_page(); $output = _batch_page();
} }
else { else {
if (empty($_SESSION['authorize_operation']) || empty($_SESSION['authorize_filetransfer_backends'])) { if (empty($_SESSION['authorize_operation']) || empty($_SESSION['authorize_filetransfer_info'])) {
$output = t('It appears you have reached this page in error.'); $output = t('It appears you have reached this page in error.');
} }
elseif (!$batch = batch_get()) { elseif (!$batch = batch_get()) {
...@@ -172,4 +172,3 @@ function authorize_access_allowed() { ...@@ -172,4 +172,3 @@ function authorize_access_allowed() {
if (!empty($output)) { if (!empty($output)) {
print theme('update_page', array('content' => $output, 'show_messages' => $show_messages)); print theme('update_page', array('content' => $output, 'show_messages' => $show_messages));
} }
<?php <?php
// $Id$
/** /**
* @file * @file
......
<?php <?php
// $Id$
/** /**
* @file * @file
...@@ -23,7 +22,7 @@ ...@@ -23,7 +22,7 @@
* - $a1, $a2: Optional additional information, which can be passed into * - $a1, $a2: Optional additional information, which can be passed into
* actions_do() and will be passed along to the action function. * actions_do() and will be passed along to the action function.
* *
* @} End of "defgroup actions". * @}
*/ */
/** /**
...@@ -49,6 +48,7 @@ ...@@ -49,6 +48,7 @@
* Passed along to the callback. * Passed along to the callback.
* @param $a2 * @param $a2
* Passed along to the callback. * Passed along to the callback.
*
* @return * @return
* An associative array containing the results of the functions that * An associative array containing the results of the functions that
* perform the actions, keyed on action ID. * perform the actions, keyed on action ID.
...@@ -150,6 +150,7 @@ function actions_do($action_ids, $object = NULL, $context = NULL, $a1 = NULL, $a ...@@ -150,6 +150,7 @@ function actions_do($action_ids, $object = NULL, $context = NULL, $a1 = NULL, $a
* *
* @param $reset * @param $reset
* Reset the action info static cache. * Reset the action info static cache.
*
* @return * @return
* An associative array keyed on action function name, with the same format * An associative array keyed on action function name, with the same format
* as the return value of hook_action_info(), containing all * as the return value of hook_action_info(), containing all
...@@ -177,9 +178,9 @@ function actions_list($reset = FALSE) { ...@@ -177,9 +178,9 @@ function actions_list($reset = FALSE) {
* function and the actions returned by actions_list() are partially * function and the actions returned by actions_list() are partially
* synchronized. Non-configurable actions from hook_action_info() * synchronized. Non-configurable actions from hook_action_info()
* implementations are put into the database when actions_synchronize() is * implementations are put into the database when actions_synchronize() is
* called, which happens when admin/config/system/actions is visited. Configurable * called, which happens when admin/config/system/actions is visited.
* actions are not added to the database until they are configured in the * Configurable actions are not added to the database until they are configured
* user interface, in which case a database row is created for each * in the user interface, in which case a database row is created for each
* configuration of each action. * configuration of each action.
* *
* @return * @return
...@@ -206,6 +207,7 @@ function actions_get_all_actions() { ...@@ -206,6 +207,7 @@ function actions_get_all_actions() {
* An associative array with function names or action IDs as keys * An associative array with function names or action IDs as keys
* and associative arrays with keys 'label', 'type', etc. as values. * and associative arrays with keys 'label', 'type', etc. as values.
* This is usually the output of actions_list() or actions_get_all_actions(). * This is usually the output of actions_list() or actions_get_all_actions().
*
* @return * @return
* An associative array whose keys are hashes of the input array keys, and * An associative array whose keys are hashes of the input array keys, and
* whose corresponding values are associative arrays with components * whose corresponding values are associative arrays with components
...@@ -224,7 +226,7 @@ function actions_actions_map($actions) { ...@@ -224,7 +226,7 @@ function actions_actions_map($actions) {
} }
/** /**
* Given a hash of an action array key, returns the key (function or ID). * Returns an action array key (function or ID), given its hash.
* *
* Faster than actions_actions_map() when you only need the function name or ID. * Faster than actions_actions_map() when you only need the function name or ID.
* *
...@@ -232,6 +234,7 @@ function actions_actions_map($actions) { ...@@ -232,6 +234,7 @@ function actions_actions_map($actions) {
* Hash of a function name or action ID array key. The array key * Hash of a function name or action ID array key. The array key
* is a key into the return value of actions_list() (array key is the action * is a key into the return value of actions_list() (array key is the action
* function name) or actions_get_all_actions() (array key is the action ID). * function name) or actions_get_all_actions() (array key is the action ID).
*
* @return * @return
* The corresponding array key, or FALSE if no match is found. * The corresponding array key, or FALSE if no match is found.
*/ */
...@@ -278,7 +281,7 @@ function actions_synchronize($delete_orphans = FALSE) { ...@@ -278,7 +281,7 @@ function actions_synchronize($delete_orphans = FALSE) {
// user adds the action. // user adds the action.
if (!$array['configurable']) { if (!$array['configurable']) {
// If we already have an action ID for this action, no need to assign aid. // If we already have an action ID for this action, no need to assign aid.
if (array_key_exists($callback, $actions_in_db)) { if (isset($actions_in_db[$callback])) {
unset($actions_in_db[$callback]); unset($actions_in_db[$callback]);
} }
else { else {
...@@ -292,7 +295,7 @@ function actions_synchronize($delete_orphans = FALSE) { ...@@ -292,7 +295,7 @@ function actions_synchronize($delete_orphans = FALSE) {
'label' => $array['label'], 'label' => $array['label'],
)) ))
->execute(); ->execute();
watchdog('actions', "Action '%action' added.", array('%action' => filter_xss_admin($array['label']))); watchdog('actions', "Action '%action' added.", array('%action' => $array['label']));
} }
} }
} }
...@@ -305,14 +308,14 @@ function actions_synchronize($delete_orphans = FALSE) { ...@@ -305,14 +308,14 @@ function actions_synchronize($delete_orphans = FALSE) {
$actions = db_query('SELECT aid, label FROM {actions} WHERE callback IN (:orphaned)', array(':orphaned' => $orphaned))->fetchAll(); $actions = db_query('SELECT aid, label FROM {actions} WHERE callback IN (:orphaned)', array(':orphaned' => $orphaned))->fetchAll();
foreach ($actions as $action) { foreach ($actions as $action) {
actions_delete($action->aid); actions_delete($action->aid);
watchdog('actions', "Removed orphaned action '%action' from database.", array('%action' => filter_xss_admin($action->label))); watchdog('actions', "Removed orphaned action '%action' from database.", array('%action' => $action->label));
} }
} }
else { else {
$link = l(t('Remove orphaned actions'), 'admin/config/system/actions/orphan'); $link = l(t('Remove orphaned actions'), 'admin/config/system/actions/orphan');
$count = count($actions_in_db); $count = count($actions_in_db);
$orphans = implode(', ', $orphaned); $orphans = implode(', ', $orphaned);
watchdog('actions', format_plural($count, 'One orphaned action (%orphans) exists in the actions table. !link', '@count orphaned actions (%orphans) exist in the actions table. !link'), array('@count' => $count, '%orphans' => $orphans, '!link' => $link), WATCHDOG_WARNING); watchdog('actions', '@count orphaned actions (%orphans) exist in the actions table. !link', array('@count' => $count, '%orphans' => $orphans, '!link' => $link), WATCHDOG_INFO);
} }
} }
} }
...@@ -333,6 +336,7 @@ function actions_synchronize($delete_orphans = FALSE) { ...@@ -333,6 +336,7 @@ function actions_synchronize($delete_orphans = FALSE) {
* to Jim'. * to Jim'.
* @param $aid * @param $aid
* The ID of this action. If omitted, a new action is created. * The ID of this action. If omitted, a new action is created.
*
* @return * @return
* The ID of the action. * The ID of the action.
*/ */
...@@ -362,6 +366,7 @@ function actions_save($function, $type, $params, $label, $aid = NULL) { ...@@ -362,6 +366,7 @@ function actions_save($function, $type, $params, $label, $aid = NULL) {
* *
* @param $aid * @param $aid
* The ID of the action to retrieve. * The ID of the action to retrieve.
*
* @return * @return
* The appropriate action row from the database as an object. * The appropriate action row from the database as an object.
*/ */
...@@ -381,4 +386,3 @@ function actions_delete($aid) { ...@@ -381,4 +386,3 @@ function actions_delete($aid) {
->execute(); ->execute();
module_invoke_all('actions_delete', $aid); module_invoke_all('actions_delete', $aid);
} }
This diff is collapsed.
<?php <?php
// $Id$
/** /**
* @file * @file
...@@ -7,61 +6,63 @@ ...@@ -7,61 +6,63 @@
*/ */
/** /**
* Common interface for all Archiver classes. * Defines the common interface for all Archiver classes.
*/ */
interface ArchiverInterface { interface ArchiverInterface {
/** /**
* Constructor for a new archiver instance. * Constructs a new archiver instance.
* *
* @param $file_path * @param $file_path
* The full system path of the archive to manipulate. Only local files * The full system path of the archive to manipulate. Only local files
* are supported. If the file does not yet exist, it will be created if * are supported. If the file does not yet exist, it will be created if
* appropriate. * appropriate.
*/ */
public function __construct($file_path); public function __construct($file_path);
/** /**
* Add the specified file or directory to the archive. * Adds the specified file or directory to the archive.
* *
* @param $file_path * @param $file_path
* The full system path of the file or directory to add. Only local files * The full system path of the file or directory to add. Only local files
* and directories are supported. * and directories are supported.
*
* @return ArchiverInterface * @return ArchiverInterface
* The called object. * The called object.
*/ */
public function add($file_path); public function add($file_path);
/** /**
* Remove the specified file from the archive. * Removes the specified file from the archive.
* *
* @param $path * @param $path
* The file name relative to the root of the archive to remove. * The file name relative to the root of the archive to remove.
*
* @return ArchiverInterface * @return ArchiverInterface
* The called object. * The called object.
*/ */
public function remove($path); public function remove($path);
/** /**
* Extract multiple files in the archive to the specified path. * Extracts multiple files in the archive to the specified path.
* *
* @param $path * @param $path
* A full system path of the directory to which to extract files. * A full system path of the directory to which to extract files.
* @param $files * @param $files
* Optionally specify a list of files to be extracted. Files are * Optionally specify a list of files to be extracted. Files are
* relative to the root of the archive. If not specified, all files * relative to the root of the archive. If not specified, all files
* in the archive will be extracted * in the archive will be extracted.
*
* @return ArchiverInterface * @return ArchiverInterface
* The called object. * The called object.
*/ */
public function extract($path, Array $files = array()); public function extract($path, array $files = array());
/** /**
* List all files in the archive. * Lists all files in the archive.
* *
* @return * @return
* An array of file names relative to the root of the archive. * An array of file names relative to the root of the archive.
*/ */
public function listContents(); public function listContents();
} }
<?php <?php
// $Id$
/** /**
* @file * @file
...@@ -7,13 +6,19 @@ ...@@ -7,13 +6,19 @@
*/ */
/** /**
* Build the form for choosing a FileTransfer type and supplying credentials. * Form constructor for the file transfer authorization form.
*
* Allows the user to choose a FileTransfer type and supply credentials.
*
* @see authorize_filetransfer_form_validate()
* @see authorize_filetransfer_form_submit()
* @ingroup forms
*/ */
function authorize_filetransfer_form($form_state) { function authorize_filetransfer_form($form, &$form_state) {
global $base_url, $is_https; global $base_url, $is_https;
$form = array(); $form = array();
// If possible, we want to post this form securely via https. // If possible, we want to post this form securely via HTTPS.
$form['#https'] = TRUE; $form['#https'] = TRUE;
// CSS we depend on lives in modules/system/maintenance.css, which is loaded // CSS we depend on lives in modules/system/maintenance.css, which is loaded
...@@ -21,15 +26,18 @@ function authorize_filetransfer_form($form_state) { ...@@ -21,15 +26,18 @@ function authorize_filetransfer_form($form_state) {
$form['#attached']['js'][] = $base_url . '/misc/authorize.js'; $form['#attached']['js'][] = $base_url . '/misc/authorize.js';
// Get all the available ways to transfer files. // Get all the available ways to transfer files.
if (empty($_SESSION['authorize_filetransfer_backends'])) { if (empty($_SESSION['authorize_filetransfer_info'])) {
drupal_set_message(t('Unable to continue, no available methods of file transfer'), 'error'); drupal_set_message(t('Unable to continue, no available methods of file transfer'), 'error');
return array(); return array();
} }
$available_backends = $_SESSION['authorize_filetransfer_backends']; $available_backends = $_SESSION['authorize_filetransfer_info'];
uasort($available_backends, 'drupal_sort_weight');
if (!$is_https) { if (!$is_https) {
drupal_set_message(t('WARNING: You are not using an encrypted connection, so your password will be sent in plain text. <a href="@https-link">Learn more</a>.', array('@https-link' => 'http://drupal.org/https-information')), 'error'); $form['information']['https_warning'] = array(
'#prefix' => '<div class="messages error">',
'#markup' => t('WARNING: You are not using an encrypted connection, so your password will be sent in plain text. <a href="@https-link">Learn more</a>.', array('@https-link' => 'http://drupal.org/https-information')),
'#suffix' => '</div>',
);
} }
// Decide on a default backend. // Decide on a default backend.
...@@ -78,17 +86,20 @@ function authorize_filetransfer_form($form_state) { ...@@ -78,17 +86,20 @@ function authorize_filetransfer_form($form_state) {
'#attributes' => array('style' => 'display:none'), '#attributes' => array('style' => 'display:none'),
); );
// Build a hidden fieldset for each one. // Build a container for each connection type.
foreach ($available_backends as $name => $backend) { foreach ($available_backends as $name => $backend) {
$form['connection_settings']['authorize_filetransfer_default']['#options'][$name] = $backend['title']; $form['connection_settings']['authorize_filetransfer_default']['#options'][$name] = $backend['title'];
$form['connection_settings'][$name] = array( $form['connection_settings'][$name] = array(
'#type' => 'fieldset', '#type' => 'container',
'#attributes' => array('class' => array("filetransfer-$name", 'filetransfer')), '#attributes' => array('class' => array("filetransfer-$name", 'filetransfer')),
'#title' => t('@backend connection settings', array('@backend' => $backend['title'])), );
// We can't use #prefix on the container itself since then the header won't
// be hidden and shown when the containers are being manipulated via JS.
$form['connection_settings'][$name]['header'] = array(
'#markup' => '<h4>' . t('@backend connection settings', array('@backend' => $backend['title'])) . '</h4>',
); );
$current_settings = variable_get('authorize_filetransfer_connection_settings_' . $name, array()); $form['connection_settings'][$name] += _authorize_filetransfer_connection_settings($name);
$form['connection_settings'][$name] += system_get_filetransfer_settings_form($name, $current_settings);
// Start non-JS code. // Start non-JS code.
if (isset($form_state['values']['connection_settings']['authorize_filetransfer_default']) && $form_state['values']['connection_settings']['authorize_filetransfer_default'] == $name) { if (isset($form_state['values']['connection_settings']['authorize_filetransfer_default']) && $form_state['values']['connection_settings']['authorize_filetransfer_default'] == $name) {
...@@ -113,7 +124,7 @@ function authorize_filetransfer_form($form_state) { ...@@ -113,7 +124,7 @@ function authorize_filetransfer_form($form_state) {
'#type' => 'submit', '#type' => 'submit',
'#value' => t('Change connection type'), '#value' => t('Change connection type'),
'#weight' => -5, '#weight' => -5,
'#attributes' => array('class' => 'filetransfer-change-connection-type'), '#attributes' => array('class' => array('filetransfer-change-connection-type')),
); );
} }
// End non-JS code. // End non-JS code.
...@@ -122,11 +133,76 @@ function authorize_filetransfer_form($form_state) { ...@@ -122,11 +133,76 @@ function authorize_filetransfer_form($form_state) {
} }
/** /**
* Validate callback for the filetransfer authorization form. * Generates the Form API array for a given connection backend's settings.
*
* @param $backend
* The name of the backend (e.g. 'ftp', 'ssh', etc).
*
* @return
* Form API array of connection settings for the given backend.
*
* @see hook_filetransfer_backends()
*/
function _authorize_filetransfer_connection_settings($backend) {
$defaults = variable_get('authorize_filetransfer_connection_settings_' . $backend, array());
$form = array();
// Create an instance of the file transfer class to get its settings form.
$filetransfer = authorize_get_filetransfer($backend);
if ($filetransfer) {
$form = $filetransfer->getSettingsForm();
}
// Fill in the defaults based on the saved settings, if any.
_authorize_filetransfer_connection_settings_set_defaults($form, NULL, $defaults);
return $form;
}
/**
* Sets the default settings on a file transfer connection form recursively.
*
* The default settings for the file transfer connection forms are saved in
* the database. The settings are stored as a nested array in the case of a
* settings form that has fieldsets or otherwise uses a nested structure.
* Therefore, to properly add defaults, we need to walk through all the
* children form elements and process those defaults recursively.
*
* @param $element
* Reference to the Form API form element we're operating on.
* @param $key
* The key for our current form element, if any.
* @param array $defaults
* The default settings for the file transfer backend we're operating on.
*/
function _authorize_filetransfer_connection_settings_set_defaults(&$element, $key, array $defaults) {
// If we're operating on a form element which isn't a fieldset, and we have
// a default setting saved, stash it in #default_value.
if (!empty($key) && isset($defaults[$key]) && isset($element['#type']) && $element['#type'] != 'fieldset') {
$element['#default_value'] = $defaults[$key];
}
// Now, we walk through all the child elements, and recursively invoke
// ourself on each one. Since the $defaults settings array can be nested
// (because of #tree, any values inside fieldsets will be nested), if
// there's a subarray of settings for the form key we're currently
// processing, pass in that subarray to the recursive call. Otherwise, just
// pass on the whole $defaults array.
foreach (element_children($element) as $child_key) {
_authorize_filetransfer_connection_settings_set_defaults($element[$child_key], $child_key, ((isset($defaults[$key]) && is_array($defaults[$key])) ? $defaults[$key] : $defaults));
}
}
/**
* Form validation handler for authorize_filetransfer_form().
* *
* @see authorize_filetransfer_form() * @see authorize_filetransfer_form()
* @see authorize_filetransfer_submit()
*/ */
function authorize_filetransfer_form_validate($form, &$form_state) { function authorize_filetransfer_form_validate($form, &$form_state) {
// Only validate the form if we have collected all of the user input and are
// ready to proceed with updating or installing.
if ($form_state['triggering_element']['#name'] != 'process_updates') {
return;
}
if (isset($form_state['values']['connection_settings'])) { if (isset($form_state['values']['connection_settings'])) {
$backend = $form_state['values']['connection_settings']['authorize_filetransfer_default']; $backend = $form_state['values']['connection_settings']['authorize_filetransfer_default'];
$filetransfer = authorize_get_filetransfer($backend, $form_state['values']['connection_settings'][$backend]); $filetransfer = authorize_get_filetransfer($backend, $form_state['values']['connection_settings'][$backend]);
...@@ -137,19 +213,25 @@ function authorize_filetransfer_form_validate($form, &$form_state) { ...@@ -137,19 +213,25 @@ function authorize_filetransfer_form_validate($form, &$form_state) {
$filetransfer->connect(); $filetransfer->connect();
} }
catch (Exception $e) { catch (Exception $e) {
form_set_error('connection_settings', $e->getMessage()); // The format of this error message is similar to that used on the
// database connection form in the installer.
form_set_error('connection_settings', t('Failed to connect to the server. The server reports the following message: !message For more help installing or updating code on your server, see the <a href="@handbook_url">handbook</a>.', array(
'!message' => '<p class="error">' . $e->getMessage() . '</p>',
'@handbook_url' => 'http://drupal.org/documentation/install/modules-themes',
)));
} }
} }
} }
/** /**
* Submit callback when a file transfer is being authorized. * Form submission handler for authorize_filetransfer_form().
* *
* @see authorize_filetransfer_form() * @see authorize_filetransfer_form()
* @see authorize_filetransfer_validate()
*/ */
function authorize_filetransfer_form_submit($form, &$form_state) { function authorize_filetransfer_form_submit($form, &$form_state) {
global $base_url; global $base_url;
switch ($form_state['clicked_button']['#name']) { switch ($form_state['triggering_element']['#name']) {
case 'process_updates': case 'process_updates':
// Save the connection settings to the DB. // Save the connection settings to the DB.
...@@ -205,7 +287,7 @@ function authorize_filetransfer_form_submit($form, &$form_state) { ...@@ -205,7 +287,7 @@ function authorize_filetransfer_form_submit($form, &$form_state) {
} }
/** /**
* Run the operation specified in $_SESSION['authorize_operation'] * Runs the operation specified in $_SESSION['authorize_operation'].
* *
* @param $filetransfer * @param $filetransfer
* The FileTransfer object to use for running the operation. * The FileTransfer object to use for running the operation.
...@@ -215,7 +297,7 @@ function authorize_run_operation($filetransfer) { ...@@ -215,7 +297,7 @@ function authorize_run_operation($filetransfer) {
unset($_SESSION['authorize_operation']); unset($_SESSION['authorize_operation']);
if (!empty($operation['page_title'])) { if (!empty($operation['page_title'])) {
drupal_set_title(check_plain($operation['page_title'])); drupal_set_title($operation['page_title']);
} }
require_once DRUPAL_ROOT . '/' . $operation['file']; require_once DRUPAL_ROOT . '/' . $operation['file'];
...@@ -223,21 +305,30 @@ function authorize_run_operation($filetransfer) { ...@@ -223,21 +305,30 @@ function authorize_run_operation($filetransfer) {
} }
/** /**
* Get a FileTransfer class for a specific transfer method and settings. * Gets a FileTransfer class for a specific transfer method and settings.
* *
* @param $backend * @param $backend
* The FileTransfer backend to get the class for. * The FileTransfer backend to get the class for.
* @param $settings * @param $settings
* Array of settings for the FileTransfer. * Array of settings for the FileTransfer.
*
* @return * @return
* An instantiated FileTransfer object for the requested method and settings, * An instantiated FileTransfer object for the requested method and settings,
* or FALSE if there was an error finding or instantiating it. * or FALSE if there was an error finding or instantiating it.
*/ */
function authorize_get_filetransfer($backend, $settings = array()) { function authorize_get_filetransfer($backend, $settings = array()) {
$filetransfer = FALSE; $filetransfer = FALSE;
if (!empty($_SESSION['authorize_filetransfer_backends'][$backend])) { if (!empty($_SESSION['authorize_filetransfer_info'][$backend])) {
$filetransfer = call_user_func_array(array($_SESSION['authorize_filetransfer_backends'][$backend]['class'], 'factory'), array(DRUPAL_ROOT, $settings)); $backend_info = $_SESSION['authorize_filetransfer_info'][$backend];
if (!empty($backend_info['file'])) {
$file = $backend_info['file path'] . '/' . $backend_info['file'];
require_once $file;
}
if (class_exists($backend_info['class'])) {
// PHP 5.2 doesn't support $class::factory() syntax, so we have to
// use call_user_func_array() until we can require PHP 5.3.
$filetransfer = call_user_func_array(array($backend_info['class'], 'factory'), array(DRUPAL_ROOT, $settings));
}
} }
return $filetransfer; return $filetransfer;
} }
<?php <?php
// $Id$
/** /**
* @file * @file
...@@ -22,6 +20,7 @@ ...@@ -22,6 +20,7 @@
* @param $id * @param $id
* The ID of the batch to load. When a progressive batch is being processed, * The ID of the batch to load. When a progressive batch is being processed,
* the relevant ID is found in $_REQUEST['id']. * the relevant ID is found in $_REQUEST['id'].
*
* @return * @return
* An array representing the batch, or FALSE if no batch was found. * An array representing the batch, or FALSE if no batch was found.
*/ */
...@@ -37,7 +36,7 @@ function batch_load($id) { ...@@ -37,7 +36,7 @@ function batch_load($id) {
} }
/** /**
* State-based dispatcher for the batch processing page. * Renders the batch processing page based on the current state of the batch.
* *
* @see _batch_shutdown() * @see _batch_shutdown()
*/ */
...@@ -95,7 +94,7 @@ function _batch_page() { ...@@ -95,7 +94,7 @@ function _batch_page() {
} }
/** /**
* Initialize the batch processing. * Initializes the batch processing.
* *
* JavaScript-enabled clients are identified by the 'has_js' cookie set in * JavaScript-enabled clients are identified by the 'has_js' cookie set in
* drupal.js. If no JavaScript-enabled page has been visited during the current * drupal.js. If no JavaScript-enabled page has been visited during the current
...@@ -111,7 +110,7 @@ function _batch_start() { ...@@ -111,7 +110,7 @@ function _batch_start() {
} }
/** /**
* Output a batch processing page with JavaScript support. * Outputs a batch processing page with JavaScript support.
* *
* This initializes the batch and error messages. Note that in JavaScript-based * This initializes the batch and error messages. Note that in JavaScript-based
* processing, the batch processing page is displayed only once and updated via * processing, the batch processing page is displayed only once and updated via
...@@ -139,14 +138,13 @@ function _batch_progress_page_js() { ...@@ -139,14 +138,13 @@ function _batch_progress_page_js() {
), ),
); );
drupal_add_js($js_setting, 'setting'); drupal_add_js($js_setting, 'setting');
drupal_add_js('misc/progress.js', array('cache' => FALSE)); drupal_add_library('system', 'drupal.batch');
drupal_add_js('misc/batch.js', array('cache' => FALSE));
return '<div id="progress"></div>'; return '<div id="progress"></div>';
} }
/** /**
* Do one execution pass in JavaScript-mode and return progress to the browser. * Does one execution pass with JavaScript and returns progress to the browser.
* *
* @see _batch_progress_page_js() * @see _batch_progress_page_js()
* @see _batch_process() * @see _batch_process()
...@@ -166,7 +164,7 @@ function _batch_do() { ...@@ -166,7 +164,7 @@ function _batch_do() {
} }
/** /**
* Output a batch processing page without JavaScript support. * Outputs a batch processing page without JavaScript support.
* *
* @see _batch_process() * @see _batch_process()
*/ */
...@@ -230,7 +228,7 @@ function _batch_progress_page_nojs() { ...@@ -230,7 +228,7 @@ function _batch_progress_page_nojs() {
} }
/** /**
* Process sets in a batch. * Processes sets in a batch.
* *
* If the batch was marked for progressive execution (default), this executes as * If the batch was marked for progressive execution (default), this executes as
* many operations in batch sets until an execution time of 1 second has been * many operations in batch sets until an execution time of 1 second has been
...@@ -285,7 +283,7 @@ function _batch_process() { ...@@ -285,7 +283,7 @@ function _batch_process() {
); );
call_user_func_array($function, array_merge($args, array(&$batch_context))); call_user_func_array($function, array_merge($args, array(&$batch_context)));
if ($finished == 1) { if ($finished >= 1) {
// Make sure this step is not counted twice when computing $current. // Make sure this step is not counted twice when computing $current.
$finished = 0; $finished = 0;
// Remove the processed operation and clear the sandbox. // Remove the processed operation and clear the sandbox.
...@@ -341,9 +339,11 @@ function _batch_process() { ...@@ -341,9 +339,11 @@ function _batch_process() {
$progress_message = $old_set['progress_message']; $progress_message = $old_set['progress_message'];
} }
// Total progress is the number of operations that have fully run plus the
// completion level of the current operation.
$current = $total - $remaining + $finished; $current = $total - $remaining + $finished;
$percentage = _batch_api_percentage($total, $current); $percentage = _batch_api_percentage($total, $current);
$elapsed = $current_set['elapsed']; $elapsed = isset($current_set['elapsed']) ? $current_set['elapsed'] : 0;
$values = array( $values = array(
'@remaining' => $remaining, '@remaining' => $remaining,
'@total' => $total, '@total' => $total,
...@@ -370,17 +370,23 @@ function _batch_process() { ...@@ -370,17 +370,23 @@ function _batch_process() {
} }
/** /**
* Helper function for _batch_process(): returns the formatted percentage. * Formats the percent completion for a batch set.
* *
* @param $total * @param $total
* The total number of operations. * The total number of operations.
* @param $current * @param $current
* The number of the current operation. * The number of the current operation. This may be a floating point number
* rather than an integer in the case of a multi-step operation that is not
* yet complete; in that case, the fractional part of $current represents the
* fraction of the operation that has been completed.
*
* @return * @return
* The properly formatted percentage, as a string. We output percentages * The properly formatted percentage, as a string. We output percentages
* using the correct number of decimal places so that we never print "100%" * using the correct number of decimal places so that we never print "100%"
* until we are finished, but we also never print more decimal places than * until we are finished, but we also never print more decimal places than
* are meaningful. * are meaningful.
*
* @see _batch_process()
*/ */
function _batch_api_percentage($total, $current) { function _batch_api_percentage($total, $current) {
if (!$total || $total == $current) { if (!$total || $total == $current) {
...@@ -392,13 +398,22 @@ function _batch_api_percentage($total, $current) { ...@@ -392,13 +398,22 @@ function _batch_api_percentage($total, $current) {
// We add a new digit at 200, 2000, etc. (since, for example, 199/200 // We add a new digit at 200, 2000, etc. (since, for example, 199/200
// would round up to 100% if we didn't). // would round up to 100% if we didn't).
$decimal_places = max(0, floor(log10($total / 2.0)) - 1); $decimal_places = max(0, floor(log10($total / 2.0)) - 1);
$percentage = sprintf('%01.' . $decimal_places . 'f', round($current / $total * 100, $decimal_places)); do {
// Calculate the percentage to the specified number of decimal places.
$percentage = sprintf('%01.' . $decimal_places . 'f', round($current / $total * 100, $decimal_places));
// When $current is an integer, the above calculation will always be
// correct. However, if $current is a floating point number (in the case
// of a multi-step batch operation that is not yet complete), $percentage
// may be erroneously rounded up to 100%. To prevent that, we add one
// more decimal place and try again.
$decimal_places++;
} while ($percentage == '100');
} }
return $percentage; return $percentage;
} }
/** /**
* Return the batch set being currently processed. * Returns the batch set being currently processed.
*/ */
function &_batch_current_set() { function &_batch_current_set() {
$batch = &batch_get(); $batch = &batch_get();
...@@ -406,7 +421,7 @@ function &_batch_current_set() { ...@@ -406,7 +421,7 @@ function &_batch_current_set() {
} }
/** /**
* Retrieve the next set in a batch. * Retrieves the next set in a batch.
* *
* If there is a subsequent set in this batch, assign it as the new set to * If there is a subsequent set in this batch, assign it as the new set to
* process and execute its form submit handler (if defined), which may add * process and execute its form submit handler (if defined), which may add
...@@ -430,7 +445,7 @@ function _batch_next_set() { ...@@ -430,7 +445,7 @@ function _batch_next_set() {
} }
/** /**
* End the batch processing. * Ends the batch processing.
* *
* Call the 'finished' callback of each batch set to allow custom handling of * Call the 'finished' callback of each batch set to allow custom handling of
* the results and resolve page redirection. * the results and resolve page redirection.
...@@ -445,10 +460,10 @@ function _batch_finished() { ...@@ -445,10 +460,10 @@ function _batch_finished() {
if (isset($batch_set['file']) && is_file($batch_set['file'])) { if (isset($batch_set['file']) && is_file($batch_set['file'])) {
include_once DRUPAL_ROOT . '/' . $batch_set['file']; include_once DRUPAL_ROOT . '/' . $batch_set['file'];
} }
if (function_exists($batch_set['finished'])) { if (is_callable($batch_set['finished'])) {
$queue = _batch_queue($batch_set); $queue = _batch_queue($batch_set);
$operations = $queue->getAllItems(); $operations = $queue->getAllItems();
$batch_set['finished']($batch_set['success'], $batch_set['results'], $operations, format_interval($batch_set['elapsed'] / 1000)); call_user_func($batch_set['finished'], $batch_set['success'], $batch_set['results'], $operations, format_interval($batch_set['elapsed'] / 1000));
} }
} }
} }
...@@ -495,9 +510,12 @@ function _batch_finished() { ...@@ -495,9 +510,12 @@ function _batch_finished() {
// Use drupal_redirect_form() to handle the redirection logic. // Use drupal_redirect_form() to handle the redirection logic.
drupal_redirect_form($_batch['form_state']); drupal_redirect_form($_batch['form_state']);
// If no redirection happened, save the final $form_state value to be // If no redirection happened, redirect to the originating page. In case the
// retrieved by drupal_get_form() and redirect to the originating page. // form needs to be rebuilt, save the final $form_state for
$_SESSION['batch_form_state'] = $_batch['form_state']; // drupal_build_form().
if (!empty($_batch['form_state']['rebuild'])) {
$_SESSION['batch_form_state'] = $_batch['form_state'];
}
$function = $_batch['redirect_callback']; $function = $_batch['redirect_callback'];
if (function_exists($function)) { if (function_exists($function)) {
$function($_batch['source_url'], array('query' => array('op' => 'finish', 'id' => $_batch['id']))); $function($_batch['source_url'], array('query' => array('op' => 'finish', 'id' => $_batch['id'])));
...@@ -506,7 +524,10 @@ function _batch_finished() { ...@@ -506,7 +524,10 @@ function _batch_finished() {
} }
/** /**
* Shutdown function; store the current batch data for the next request. * Shutdown function: Stores the current batch data for the next request.
*
* @see _batch_page()
* @see drupal_register_shutdown_function()
*/ */
function _batch_shutdown() { function _batch_shutdown() {
if ($batch = batch_get()) { if ($batch = batch_get()) {
...@@ -516,4 +537,3 @@ function _batch_shutdown() { ...@@ -516,4 +537,3 @@ function _batch_shutdown() {
->execute(); ->execute();
} }
} }