Skip to content
Commits on Source (1632)
# 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
...@@ -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>
...@@ -20,7 +20,7 @@ ErrorDocument 404 /index.php ...@@ -20,7 +20,7 @@ ErrorDocument 404 /index.php
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.
...@@ -56,6 +56,17 @@ DirectoryIndex index.php index.html index.htm ...@@ -56,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
...@@ -78,14 +89,15 @@ DirectoryIndex index.php index.html index.htm ...@@ -78,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.
...@@ -129,3 +141,9 @@ DirectoryIndex index.php index.html index.htm ...@@ -129,3 +141,9 @@ DirectoryIndex index.php index.html index.htm
</FilesMatch> </FilesMatch>
</IfModule> </IfModule>
</IfModule> </IfModule>
# 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.
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
...@@ -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
...@@ -18,20 +18,23 @@ initial database files. Next you must log in and set the access database rights: ...@@ -18,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:
......
...@@ -20,8 +20,10 @@ Drupal requires: ...@@ -20,8 +20,10 @@ Drupal requires:
- MySQL 5.0.15 (or greater) (http://www.mysql.com/). - MySQL 5.0.15 (or greater) (http://www.mysql.com/).
- MariaDB 5.1.44 (or greater) (http://mariadb.org/). MariaDB is a fully - MariaDB 5.1.44 (or greater) (http://mariadb.org/). MariaDB is a fully
compatible drop-in replacement for MySQL. compatible drop-in replacement for MySQL.
- Percona Server 5.1.70 (or greater) (http://www.percona.com/). Percona
Server is a backwards-compatible replacement for MySQL.
- PostgreSQL 8.3 (or greater) (http://www.postgresql.org/). - PostgreSQL 8.3 (or greater) (http://www.postgresql.org/).
- SQLite 3.4.2 (or greater) (http://www.sqlite.org/). - SQLite 3.3.7 (or greater) (http://www.sqlite.org/).
For more detailed information about Drupal requirements, including a list of For more detailed information about Drupal requirements, including a list of
PHP extensions and configurations that are required, see "System requirements" PHP extensions and configurations that are required, see "System requirements"
...@@ -89,8 +91,8 @@ INSTALLATION ...@@ -89,8 +91,8 @@ INSTALLATION
- Download a translation file for the correct Drupal version and language - Download a translation file for the correct Drupal version and language
from the translation server: http://localize.drupal.org/translate/downloads from the translation server: http://localize.drupal.org/translate/downloads
- Place the file into your installation profile's translations - Place the file into your installation profile's translations directory.
directory. For instance, if you are using the Standard install profile, For instance, if you are using the Standard installation profile,
move the .po file into the directory: move the .po file into the directory:
profiles/standard/translations/ profiles/standard/translations/
......
Drupal core is maintained by the community. To participate, go to 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
http://drupal.org/contribute contribute in other ways -- see https://www.drupal.org/contribute to find out
how.
The people listed here have agreed to do more quality assurance work for
particular areas of Drupal. All of them are subject to change.
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
--------------------- ---------------------
The Drupal Core component maintainers oversee the development of Drupal
subsystems. See https://www.drupal.org/contribute/core-maintainers for more
information on their responsibilities, and to find out how to become a component
maintainer. Current component maintainers for Drupal 7:
Ajax system Ajax system
- Alex Bronstein 'effulgentsia' <http://drupal.org/user/78040> - Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
- Randy Fay 'rfay' <http://drupal.org/user/30906> - Earl Miles 'merlinofchaos' https://www.drupal.org/u/merlinofchaos
- Earl Miles 'merlinofchaos' <http://drupal.org/user/26979>
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 Cache system
- Damien Tournoud 'DamZ' <http://drupal.org/user/22211> - Damien Tournoud 'DamZ' https://www.drupal.org/u/damien-tournoud
- Nathaniel Catchpole 'catch' <http://drupal.org/user/35733> - 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' <http://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 Database update system
- Károly Négyesi 'chx' <http://drupal.org/user/9446> - 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 Luisi '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' <http://drupal.org/user/32095> - 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
XML-RPC system XML-RPC system
- Frederic G. Marand 'fgm' <http://drupal.org/user/27985> - 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 'brandonojc' <http://drupal.org/user/186415> - Brandon Bowersox-Johnson 'bowersox' https://www.drupal.org/u/bowersox
Documentation Documentation
- Ariane Khachatourians 'arianek' <http://drupal.org/user/158886> - 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
...@@ -151,144 +167,141 @@ Aggregator module ...@@ -151,144 +167,141 @@ Aggregator module
- ? - ?
Block module Block module
- John Albin Wilkins 'JohnAlbin' <http://drupal.org/user/32095> - 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' <http://drupal.org/user/395439> - 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
- Vojtech Kusy 'wojtha' <http://drupal.org/user/56154> - Vojtech Kusy 'wojtha' https://www.drupal.org/u/wojtha
- Heine Deelstra 'Heine' <http://drupal.org/user/17943> - Christian Schmidt 'c960657' https://www.drupal.org/u/c960657
- Christian Schmidt 'c960657' <http://drupal.org/user/216078> - Damien Tournoud 'DamZ' https://www.drupal.org/u/damien-tournoud
- Damien Tournoud 'DamZ' <http://drupal.org/user/22211>
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
- Doug Green 'douggreen' <http://drupal.org/user/29191> - Doug Green 'douggreen' https://www.drupal.org/u/douggreen
Shortcut module Shortcut module
- David Rothstein 'David_Rothstein' <http://drupal.org/user/124982> - David Rothstein 'David_Rothstein' https://www.drupal.org/u/david_rothstein
- Kristof De Jaeger 'swentel' <http://drupal.org/user/107403>
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
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 Bartik theme
- Jen Simmons 'jensimmons' <http://drupal.org/user/140882> - Jen Simmons 'jensimmons' https://www.drupal.org/u/jensimmons
- Jeff Burns 'Jeff Burnz' <http://drupal.org/user/61393> - Jeff Burns 'Jeff Burnz' https://www.drupal.org/u/jeff-burnz
Garland theme Garland theme
- John Albin Wilkins 'JohnAlbin' <http://drupal.org/user/32095> - John Albin Wilkins 'JohnAlbin' https://www.drupal.org/u/johnalbin
Seven theme Seven theme
- Jeff Burns 'Jeff Burnz' <http://drupal.org/user/61393> - Jeff Burns 'Jeff Burnz' https://www.drupal.org/u/jeff-burnz
Stark theme Stark theme
- John Albin Wilkins 'JohnAlbin' <http://drupal.org/user/32095> - John Albin Wilkins 'JohnAlbin' https://www.drupal.org/u/johnalbin
...@@ -4,6 +4,7 @@ CONTENTS OF THIS FILE ...@@ -4,6 +4,7 @@ CONTENTS OF THIS FILE
* About Drupal * About Drupal
* Configuration and features * Configuration and features
* Installation profiles
* Appearance * Appearance
* Developing for Drupal * Developing for Drupal
...@@ -43,6 +44,40 @@ More about configuration: ...@@ -43,6 +44,40 @@ More about configuration:
http://drupal.org/project/modules http://drupal.org/project/modules
* See also: "Developing for Drupal" for writing your own modules, below. * 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 APPEARANCE
---------- ----------
......
...@@ -64,6 +64,9 @@ following the instructions in the INTRODUCTION section at the top of this file: ...@@ -64,6 +64,9 @@ following the instructions in the INTRODUCTION section at the top of this file:
Sometimes an update includes changes to default.settings.php (this will be 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: noted in the release notes). If that's the case, follow these steps:
- Locate your settings.php file in the /sites/* directory. (Typically
sites/default.)
- Make a backup copy of your settings.php file, with a different file name. - Make a backup copy of your settings.php file, with a different file name.
- Make a copy of the new default.settings.php file, and name the copy - Make a copy of the new default.settings.php file, and name the copy
...@@ -74,6 +77,13 @@ following the instructions in the INTRODUCTION section at the top of this file: ...@@ -74,6 +77,13 @@ following the instructions in the INTRODUCTION section at the top of this file:
database information, and you will also want to copy in any other database information, and you will also want to copy in any other
customizations you have added. customizations you have added.
You can find the release notes for your version at
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.
4. Download the latest Drupal 7.x release from http://drupal.org to a 4. 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 directory outside of your web root. Extract the archive and copy the files
into your Drupal directory. into your Drupal directory.
...@@ -141,15 +151,19 @@ following the instructions in the INTRODUCTION section at the top of this file: ...@@ -141,15 +151,19 @@ following the instructions in the INTRODUCTION section at the top of this file:
download Drupal 6.x and follow the instructions in its UPGRADE.txt. This download Drupal 6.x and follow the instructions in its UPGRADE.txt. This
document only applies for upgrades from 6.x to 7.x. document only applies for upgrades from 6.x to 7.x.
3. Log in as user ID 1 (the site maintenance user). 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).
4. Go to Administer > Site configuration > Site maintenance. Select 5. Go to Administer > Site configuration > Site maintenance. Select
"Off-line" and save the configuration. "Off-line" and save the configuration.
5. Go to Administer > Site building > Themes. Enable "Garland" and select it as 6. Go to Administer > Site building > Themes. Enable "Garland" and select it as
the default theme. the default theme.
6. Go to Administer > Site building > Modules. Disable all modules that are not 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 listed under "Core - required" or "Core - optional". It is possible that some
modules cannot be disabled, because others depend on them. Repeat this step modules cannot be disabled, because others depend on them. Repeat this step
until all non-core modules are disabled. until all non-core modules are disabled.
...@@ -158,21 +172,21 @@ following the instructions in the INTRODUCTION section at the top of this file: ...@@ -158,21 +172,21 @@ following the instructions in the INTRODUCTION section at the top of this file:
no longer need their data, then you can uninstall them under the Uninstall no longer need their data, then you can uninstall them under the Uninstall
tab after disabling them. tab after disabling them.
7. On the command line or in your FTP client, remove the file 8. On the command line or in your FTP client, remove the file
sites/default/default.settings.php sites/default/default.settings.php
8. Remove all old core files and directories, except for the 'sites' directory 9. Remove all old core files and directories, except for the 'sites' directory
and any custom files you added elsewhere. and any custom files you added elsewhere.
If you made modifications to files like .htaccess or robots.txt, you will 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. need to re-apply them from your backup, after the new files are in place.
9. If you uninstalled any modules, remove them from the sites/all/modules and 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 other sites/*/modules directories. Leave other modules in place, even though
they are incompatible with Drupal 7.x. they are incompatible with Drupal 7.x.
10. Download the latest Drupal 7.x release from http://drupal.org to a 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 directory outside of your web root. Extract the archive and copy the files
into your Drupal directory. into your Drupal directory.
...@@ -191,14 +205,14 @@ following the instructions in the INTRODUCTION section at the top of this file: ...@@ -191,14 +205,14 @@ following the instructions in the INTRODUCTION section at the top of this file:
from http://drupal.org using your web browser, extract it, and then use an from http://drupal.org using your web browser, extract it, and then use an
FTP client to upload the files to your web root. FTP client to upload the files to your web root.
11. Re-apply any modifications to files such as .htaccess or robots.txt. 12. Re-apply any modifications to files such as .htaccess or robots.txt.
12. Make your settings.php file writeable, so that the update process can 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 convert it to the format of Drupal 7.x. settings.php is usually located in
sites/default/settings.php sites/default/settings.php
13. Run update.php by visiting http://www.example.com/update.php (replace 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 www.example.com with your domain name). This will update the core database
tables. tables.
...@@ -214,17 +228,17 @@ following the instructions in the INTRODUCTION section at the top of this file: ...@@ -214,17 +228,17 @@ following the instructions in the INTRODUCTION section at the top of this file:
- Once the upgrade is done, $update_free_access must be reverted to FALSE. - Once the upgrade is done, $update_free_access must be reverted to FALSE.
14. Backup your database after the core upgrade has run. 15. Backup your database after the core upgrade has run.
15. Replace and update your non-core modules and themes, following the 16. Replace and update your non-core modules and themes, following the
procedures at http://drupal.org/node/948216 procedures at http://drupal.org/node/948216
16. Go to Administration > Reports > Status report. Verify that everything is 17. Go to Administration > Reports > Status report. Verify that everything is
working as expected. working as expected.
17. Ensure that $update_free_access is FALSE in settings.php. 18. Ensure that $update_free_access is FALSE in settings.php.
18. Go to Administration > Configuration > Development > Maintenance mode. 19. Go to Administration > Configuration > Development > Maintenance mode.
Disable the "Put site into maintenance mode" checkbox and save the Disable the "Put site into maintenance mode" checkbox and save the
configuration. configuration.
......
...@@ -4,16 +4,16 @@ ...@@ -4,16 +4,16 @@
* @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:
...@@ -21,16 +21,17 @@ ...@@ -21,16 +21,17 @@
*/ */
/** /**
* 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');
...@@ -51,7 +52,7 @@ function authorize_access_denied_page() { ...@@ -51,7 +52,7 @@ function authorize_access_denied_page() {
* 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');
...@@ -60,7 +61,6 @@ function authorize_access_allowed() { ...@@ -60,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';
...@@ -74,7 +74,7 @@ function authorize_access_allowed() { ...@@ -74,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);
......
...@@ -22,7 +22,7 @@ ...@@ -22,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". * @}
*/ */
/** /**
...@@ -48,6 +48,7 @@ ...@@ -48,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.
...@@ -149,6 +150,7 @@ function actions_do($action_ids, $object = NULL, $context = NULL, $a1 = NULL, $a ...@@ -149,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
...@@ -176,9 +178,9 @@ function actions_list($reset = FALSE) { ...@@ -176,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
...@@ -205,6 +207,7 @@ function actions_get_all_actions() { ...@@ -205,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
...@@ -223,7 +226,7 @@ function actions_actions_map($actions) { ...@@ -223,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.
* *
...@@ -231,6 +234,7 @@ function actions_actions_map($actions) { ...@@ -231,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.
*/ */
...@@ -332,6 +336,7 @@ function actions_synchronize($delete_orphans = FALSE) { ...@@ -332,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.
*/ */
...@@ -361,6 +366,7 @@ function actions_save($function, $type, $params, $label, $aid = NULL) { ...@@ -361,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.
*/ */
...@@ -380,4 +386,3 @@ function actions_delete($aid) { ...@@ -380,4 +386,3 @@ function actions_delete($aid) {
->execute(); ->execute();
module_invoke_all('actions_delete', $aid); module_invoke_all('actions_delete', $aid);
} }
...@@ -24,7 +24,8 @@ ...@@ -24,7 +24,8 @@
* ajax_form_callback() and a defined #ajax['callback'] function. * ajax_form_callback() and a defined #ajax['callback'] function.
* However, you may optionally specify a different path to request or a * However, you may optionally specify a different path to request or a
* different callback function to invoke, which can return updated HTML or can * different callback function to invoke, which can return updated HTML or can
* also return a richer set of @link ajax_commands Ajax framework commands @endlink. * also return a richer set of
* @link ajax_commands Ajax framework commands @endlink.
* *
* Standard form handling is as follows: * Standard form handling is as follows:
* - A form element has a #ajax property that includes #ajax['callback'] and * - A form element has a #ajax property that includes #ajax['callback'] and
...@@ -101,7 +102,7 @@ ...@@ -101,7 +102,7 @@
* In the above example, the 'changethis' element is Ajax-enabled. The default * In the above example, the 'changethis' element is Ajax-enabled. The default
* #ajax['event'] is 'change', so when the 'changethis' element changes, * #ajax['event'] is 'change', so when the 'changethis' element changes,
* an Ajax call is made. The form is submitted and reprocessed, and then the * an Ajax call is made. The form is submitted and reprocessed, and then the
* callback is called. In this case, the form has been automatically * callback is called. In this case, the form has been automatically
* built changing $form['replace_textfield']['#description'], so the callback * built changing $form['replace_textfield']['#description'], so the callback
* just returns that part of the form. * just returns that part of the form.
* *
...@@ -167,7 +168,7 @@ ...@@ -167,7 +168,7 @@
* displayed while awaiting a response from the callback, and add an optional * displayed while awaiting a response from the callback, and add an optional
* message. Possible keys: 'type', 'message', 'url', 'interval'. * message. Possible keys: 'type', 'message', 'url', 'interval'.
* More information is available in the * More information is available in the
* @link http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html/7 Form API Reference @endlink * @link forms_api_reference.html Form API Reference @endlink
* *
* In addition to using Form API for doing in-form modification, Ajax may be * In addition to using Form API for doing in-form modification, Ajax may be
* enabled by adding classes to buttons and links. By adding the 'use-ajax' * enabled by adding classes to buttons and links. By adding the 'use-ajax'
...@@ -188,11 +189,11 @@ ...@@ -188,11 +189,11 @@
* be converted to a JSON object and returned to the client, which will then * be converted to a JSON object and returned to the client, which will then
* iterate over the array and process it like a macro language. * iterate over the array and process it like a macro language.
* *
* Each command item is an associative array which will be converted to a command * Each command item is an associative array which will be converted to a
* object on the JavaScript side. $command_item['command'] is the type of * command object on the JavaScript side. $command_item['command'] is the type
* command, e.g. 'alert' or 'replace', and will correspond to a method in the * of command, e.g. 'alert' or 'replace', and will correspond to a method in the
* Drupal.ajax[command] space. The command array may contain any other data * Drupal.ajax[command] space. The command array may contain any other data that
* that the command needs to process, e.g. 'method', 'selector', 'settings', etc. * the command needs to process, e.g. 'method', 'selector', 'settings', etc.
* *
* Commands are usually created with a couple of helper functions, so they * Commands are usually created with a couple of helper functions, so they
* look like this: * look like this:
...@@ -210,7 +211,7 @@ ...@@ -210,7 +211,7 @@
* *
* When returning an Ajax command array, it is often useful to have * When returning an Ajax command array, it is often useful to have
* status messages rendered along with other tasks in the command array. * status messages rendered along with other tasks in the command array.
* In that case the the Ajax commands array may be constructed like this: * In that case the Ajax commands array may be constructed like this:
* @code * @code
* $commands = array(); * $commands = array();
* $commands[] = ajax_command_replace(NULL, $output); * $commands[] = ajax_command_replace(NULL, $output);
...@@ -222,13 +223,17 @@ ...@@ -222,13 +223,17 @@
*/ */
/** /**
* Render a commands array into JSON. * Renders a commands array into JSON.
* *
* @param $commands * @param $commands
* A list of macro commands generated by the use of ajax_command_*() * A list of macro commands generated by the use of ajax_command_*()
* functions. * functions.
*/ */
function ajax_render($commands = array()) { function ajax_render($commands = array()) {
// Although ajax_deliver() does this, some contributed and custom modules
// render Ajax responses without using that delivery callback.
ajax_set_verification_header();
// Ajax responses aren't rendered with html.tpl.php, so we have to call // Ajax responses aren't rendered with html.tpl.php, so we have to call
// drupal_get_css() and drupal_get_js() here, in order to have new files added // drupal_get_css() and drupal_get_js() here, in order to have new files added
// during this request to be loaded by the page. We only want to send back // during this request to be loaded by the page. We only want to send back
...@@ -250,8 +255,8 @@ function ajax_render($commands = array()) { ...@@ -250,8 +255,8 @@ function ajax_render($commands = array()) {
// reliably diffed with array_diff_key(), since the number can change // reliably diffed with array_diff_key(), since the number can change
// due to factors unrelated to the inline content, so for now, we strip // due to factors unrelated to the inline content, so for now, we strip
// the inline items from Ajax responses, and can add support for them // the inline items from Ajax responses, and can add support for them
// when drupal_add_css() and drupal_add_js() are changed to using md5() // when drupal_add_css() and drupal_add_js() are changed to use a hash
// or some other hash of the inline content. // of the inline content as the array key.
foreach ($items[$type] as $key => $item) { foreach ($items[$type] as $key => $item) {
if (is_numeric($key)) { if (is_numeric($key)) {
unset($items[$type][$key]); unset($items[$type][$key]);
...@@ -262,26 +267,20 @@ function ajax_render($commands = array()) { ...@@ -262,26 +267,20 @@ function ajax_render($commands = array()) {
} }
} }
// Settings are handled separately, later in this function, so that changes to // Render the HTML to load these files, and add AJAX commands to insert this
// the ajaxPageState setting that occur during drupal_get_css() and // HTML in the page. We pass TRUE as the $skip_alter argument to prevent the
// drupal_get_js() get included, and because the jQuery.extend() code produced // data from being altered again, as we already altered it above. Settings are
// by drupal_get_js() for adding settings isn't appropriate during an Ajax // handled separately, afterwards.
// response, because it does not pass TRUE for the "deep" parameter, and
// therefore, can clobber existing settings on the page.
if (isset($items['js']['settings'])) { if (isset($items['js']['settings'])) {
unset($items['js']['settings']); unset($items['js']['settings']);
} }
// Render the HTML to load these files, and add Ajax commands to insert this
// HTML in the page. We pass TRUE as the $skip_alter argument to prevent the
// data from being altered again, as we already altered it above.
$styles = drupal_get_css($items['css'], TRUE); $styles = drupal_get_css($items['css'], TRUE);
$scripts_footer = drupal_get_js('footer', $items['js'], TRUE); $scripts_footer = drupal_get_js('footer', $items['js'], TRUE);
$scripts_header = drupal_get_js('header', $items['js'], TRUE); $scripts_header = drupal_get_js('header', $items['js'], TRUE);
$extra_commands = array(); $extra_commands = array();
if (!empty($styles)) { if (!empty($styles)) {
$extra_commands[] = ajax_command_prepend('head', $styles); $extra_commands[] = ajax_command_add_css($styles);
} }
if (!empty($scripts_header)) { if (!empty($scripts_header)) {
$extra_commands[] = ajax_command_prepend('head', $scripts_header); $extra_commands[] = ajax_command_prepend('head', $scripts_header);
...@@ -293,12 +292,11 @@ function ajax_render($commands = array()) { ...@@ -293,12 +292,11 @@ function ajax_render($commands = array()) {
$commands = array_merge($extra_commands, $commands); $commands = array_merge($extra_commands, $commands);
} }
// Now add a command to merge changes and additions to Drupal.settings.
$scripts = drupal_add_js(); $scripts = drupal_add_js();
if (!empty($scripts['settings'])) { if (!empty($scripts['settings'])) {
$settings = $scripts['settings']; $settings = $scripts['settings'];
// Automatically extract any settings added via drupal_add_js() and make array_unshift($commands, ajax_command_settings(drupal_array_merge_deep_array($settings['data']), TRUE));
// them the first command.
array_unshift($commands, ajax_command_settings(call_user_func_array('array_merge_recursive', $settings['data']), TRUE));
} }
// Allow modules to alter any Ajax response. // Allow modules to alter any Ajax response.
...@@ -308,16 +306,17 @@ function ajax_render($commands = array()) { ...@@ -308,16 +306,17 @@ function ajax_render($commands = array()) {
} }
/** /**
* Get a form submitted via #ajax during an Ajax callback. * Gets a form submitted via #ajax during an Ajax callback.
* *
* This will load a form from the form cache used during Ajax operations. It * This will load a form from the form cache used during Ajax operations. It
* pulls the form info from $_POST. * pulls the form info from $_POST.
* *
* @return * @return
* An array containing the $form and $form_state. Use the list() function * An array containing the $form, $form_state, $form_id, $form_build_id and an
* to break these apart: * initial list of Ajax $commands. Use the list() function to break these
* apart:
* @code * @code
* list($form, $form_state, $form_id, $form_build_id) = ajax_get_form(); * list($form, $form_state, $form_id, $form_build_id, $commands) = ajax_get_form();
* @endcode * @endcode
*/ */
function ajax_get_form() { function ajax_get_form() {
...@@ -337,6 +336,17 @@ function ajax_get_form() { ...@@ -337,6 +336,17 @@ function ajax_get_form() {
drupal_exit(); drupal_exit();
} }
// When a page level cache is enabled, the form-build id might have been
// replaced from within form_get_cache. If this is the case, it is also
// necessary to update it in the browser by issuing an appropriate Ajax
// command.
$commands = array();
if (isset($form['#build_id_old']) && $form['#build_id_old'] != $form['#build_id']) {
// If the form build ID has changed, issue an Ajax command to update it.
$commands[] = ajax_command_update_build_id($form);
$form_build_id = $form['#build_id'];
}
// Since some of the submit handlers are run, redirects need to be disabled. // Since some of the submit handlers are run, redirects need to be disabled.
$form_state['no_redirect'] = TRUE; $form_state['no_redirect'] = TRUE;
...@@ -351,7 +361,7 @@ function ajax_get_form() { ...@@ -351,7 +361,7 @@ function ajax_get_form() {
$form_state['input'] = $_POST; $form_state['input'] = $_POST;
$form_id = $form['#form_id']; $form_id = $form['#form_id'];
return array($form, $form_state, $form_id, $form_build_id); return array($form, $form_state, $form_id, $form_build_id, $commands);
} }
/** /**
...@@ -368,9 +378,11 @@ function ajax_get_form() { ...@@ -368,9 +378,11 @@ function ajax_get_form() {
* #ajax['path']. If processing is required that cannot be accomplished with * #ajax['path']. If processing is required that cannot be accomplished with
* a callback, re-implement this function and set #ajax['path'] to the * a callback, re-implement this function and set #ajax['path'] to the
* enhanced function. * enhanced function.
*
* @see system_menu()
*/ */
function ajax_form_callback() { function ajax_form_callback() {
list($form, $form_state) = ajax_get_form(); list($form, $form_state, $form_id, $form_build_id, $commands) = ajax_get_form();
drupal_process_form($form['#form_id'], $form, $form_state); drupal_process_form($form['#form_id'], $form, $form_state);
// We need to return the part of the form (or some other content) that needs // We need to return the part of the form (or some other content) that needs
...@@ -382,8 +394,20 @@ function ajax_form_callback() { ...@@ -382,8 +394,20 @@ function ajax_form_callback() {
if (!empty($form_state['triggering_element'])) { if (!empty($form_state['triggering_element'])) {
$callback = $form_state['triggering_element']['#ajax']['callback']; $callback = $form_state['triggering_element']['#ajax']['callback'];
} }
if (!empty($callback) && function_exists($callback)) { if (!empty($callback) && is_callable($callback)) {
return $callback($form, $form_state); $result = $callback($form, $form_state);
if (!(is_array($result) && isset($result['#type']) && $result['#type'] == 'ajax')) {
// Turn the response into a #type=ajax array if it isn't one already.
$result = array(
'#type' => 'ajax',
'#commands' => ajax_prepare_response($result),
);
}
$result['#commands'] = array_merge($commands, $result['#commands']);
return $result;
} }
} }
...@@ -403,6 +427,9 @@ function ajax_form_callback() { ...@@ -403,6 +427,9 @@ function ajax_form_callback() {
* of the page. Therefore, system_menu() sets the 'theme callback' for * of the page. Therefore, system_menu() sets the 'theme callback' for
* 'system/ajax' to this function, and it is recommended that modules * 'system/ajax' to this function, and it is recommended that modules
* implementing other generic Ajax paths do the same. * implementing other generic Ajax paths do the same.
*
* @see system_menu()
* @see file_menu()
*/ */
function ajax_base_page_theme() { function ajax_base_page_theme() {
if (!empty($_POST['ajax_page_state']['theme']) && !empty($_POST['ajax_page_state']['theme_token'])) { if (!empty($_POST['ajax_page_state']['theme']) && !empty($_POST['ajax_page_state']['theme_token'])) {
...@@ -421,7 +448,7 @@ function ajax_base_page_theme() { ...@@ -421,7 +448,7 @@ function ajax_base_page_theme() {
} }
/** /**
* Package and send the result of a page callback to the browser as an Ajax response. * Packages and sends the result of a page callback as an Ajax response.
* *
* This function is the equivalent of drupal_deliver_html_page(), but for Ajax * This function is the equivalent of drupal_deliver_html_page(), but for Ajax
* requests. Like that function, it: * requests. Like that function, it:
...@@ -464,6 +491,9 @@ function ajax_deliver($page_callback_result) { ...@@ -464,6 +491,9 @@ function ajax_deliver($page_callback_result) {
} }
} }
// Let ajax.js know that this response is safe to process.
ajax_set_verification_header();
// Print the response. // Print the response.
$commands = ajax_prepare_response($page_callback_result); $commands = ajax_prepare_response($page_callback_result);
$json = ajax_render($commands); $json = ajax_render($commands);
...@@ -554,7 +584,30 @@ function ajax_prepare_response($page_callback_result) { ...@@ -554,7 +584,30 @@ function ajax_prepare_response($page_callback_result) {
} }
/** /**
* Perform end-of-Ajax-request tasks. * Sets a response header for ajax.js to trust the response body.
*
* It is not safe to invoke Ajax commands within user-uploaded files, so this
* header protects against those being invoked.
*
* @see Drupal.ajax.options.success()
*/
function ajax_set_verification_header() {
$added = &drupal_static(__FUNCTION__);
// User-uploaded files cannot set any response headers, so a custom header is
// used to indicate to ajax.js that this response is safe. Note that most
// Ajax requests bound using the Form API will be protected by having the URL
// flagged as trusted in Drupal.settings, so this header is used only for
// things like custom markup that gets Ajax behaviors attached.
if (empty($added)) {
drupal_add_http_header('X-Drupal-Ajax-Token', '1');
// Avoid sending the header twice.
$added = TRUE;
}
}
/**
* Performs end-of-Ajax-request tasks.
* *
* This function is the equivalent of drupal_page_footer(), but for Ajax * This function is the equivalent of drupal_page_footer(), but for Ajax
* requests. * requests.
...@@ -577,7 +630,7 @@ function ajax_footer() { ...@@ -577,7 +630,7 @@ function ajax_footer() {
} }
/** /**
* Form element process callback to handle #ajax. * Form element processing handler for the #ajax form property.
* *
* @param $element * @param $element
* An associative array containing the properties of the element. * An associative array containing the properties of the element.
...@@ -596,7 +649,7 @@ function ajax_process_form($element, &$form_state) { ...@@ -596,7 +649,7 @@ function ajax_process_form($element, &$form_state) {
} }
/** /**
* Add Ajax information about an element to the page to communicate with JavaScript. * Adds Ajax information about an element to communicate with JavaScript.
* *
* If #ajax['path'] is set on an element, this additional JavaScript is added * If #ajax['path'] is set on an element, this additional JavaScript is added
* to the page header to attach the Ajax behaviors. See ajax.js for more * to the page header to attach the Ajax behaviors. See ajax.js for more
...@@ -741,7 +794,12 @@ function ajax_pre_render_element($element) { ...@@ -741,7 +794,12 @@ function ajax_pre_render_element($element) {
$element['#attached']['js'][] = array( $element['#attached']['js'][] = array(
'type' => 'setting', 'type' => 'setting',
'data' => array('ajax' => array($element['#id'] => $settings)), 'data' => array(
'ajax' => array($element['#id'] => $settings),
'urlIsAjaxTrusted' => array(
$settings['url'] => TRUE,
),
),
); );
// Indicate that Ajax processing was successful. // Indicate that Ajax processing was successful.
...@@ -837,7 +895,8 @@ function ajax_command_insert($selector, $html, $settings = NULL) { ...@@ -837,7 +895,8 @@ function ajax_command_insert($selector, $html, $settings = NULL) {
* @return * @return
* An array suitable for use with the ajax_render() function. * An array suitable for use with the ajax_render() function.
* *
* See @link http://docs.jquery.com/Manipulation/replaceWith#content jQuery replaceWith command @endlink * See
* @link http://docs.jquery.com/Manipulation/replaceWith#content jQuery replaceWith command @endlink
*/ */
function ajax_command_replace($selector, $html, $settings = NULL) { function ajax_command_replace($selector, $html, $settings = NULL) {
return array( return array(
...@@ -1211,3 +1270,48 @@ function ajax_command_restripe($selector) { ...@@ -1211,3 +1270,48 @@ function ajax_command_restripe($selector) {
); );
} }
/**
* Creates a Drupal Ajax 'update_build_id' command.
*
* This command updates the value of a hidden form_build_id input element on a
* form. It requires the form passed in to have keys for both the old build ID
* in #build_id_old and the new build ID in #build_id.
*
* The primary use case for this Ajax command is to serve a new build ID to a
* form served from the cache to an anonymous user, preventing one anonymous
* user from accessing the form state of another anonymous users on Ajax enabled
* forms.
*
* @param $form
* The form array representing the form whose build ID should be updated.
*/
function ajax_command_update_build_id($form) {
return array(
'command' => 'updateBuildId',
'old' => $form['#build_id_old'],
'new' => $form['#build_id'],
);
}
/**
* Creates a Drupal Ajax 'add_css' command.
*
* This method will add css via ajax in a cross-browser compatible way.
*
* This command is implemented by Drupal.ajax.prototype.commands.add_css()
* defined in misc/ajax.js.
*
* @param $styles
* A string that contains the styles to be added.
*
* @return
* An array suitable for use with the ajax_render() function.
*
* @see misc/ajax.js
*/
function ajax_command_add_css($styles) {
return array(
'command' => 'add_css',
'data' => $styles,
);
}
...@@ -6,61 +6,63 @@ ...@@ -6,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();
} }
...@@ -6,13 +6,19 @@ ...@@ -6,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, &$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
...@@ -127,10 +133,11 @@ function authorize_filetransfer_form($form, &$form_state) { ...@@ -127,10 +133,11 @@ function authorize_filetransfer_form($form, &$form_state) {
} }
/** /**
* Generate the Form API array for the settings for a given connection backend. * Generates the Form API array for a given connection backend's settings.
* *
* @param $backend * @param $backend
* The name of the backend (e.g. 'ftp', 'ssh', etc). * The name of the backend (e.g. 'ftp', 'ssh', etc).
*
* @return * @return
* Form API array of connection settings for the given backend. * Form API array of connection settings for the given backend.
* *
...@@ -151,7 +158,7 @@ function _authorize_filetransfer_connection_settings($backend) { ...@@ -151,7 +158,7 @@ function _authorize_filetransfer_connection_settings($backend) {
} }
/** /**
* Recursively fill in the default settings on a file transfer connection 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 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 * the database. The settings are stored as a nested array in the case of a
...@@ -165,8 +172,6 @@ function _authorize_filetransfer_connection_settings($backend) { ...@@ -165,8 +172,6 @@ function _authorize_filetransfer_connection_settings($backend) {
* The key for our current form element, if any. * The key for our current form element, if any.
* @param array $defaults * @param array $defaults
* The default settings for the file transfer backend we're operating on. * The default settings for the file transfer backend we're operating on.
* @return
* Nothing, this function just sets $element['#default_value'] if needed.
*/ */
function _authorize_filetransfer_connection_settings_set_defaults(&$element, $key, array $defaults) { 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 // If we're operating on a form element which isn't a fieldset, and we have
...@@ -186,9 +191,10 @@ function _authorize_filetransfer_connection_settings_set_defaults(&$element, $ke ...@@ -186,9 +191,10 @@ function _authorize_filetransfer_connection_settings_set_defaults(&$element, $ke
} }
/** /**
* Validate callback for the filetransfer authorization form. * 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 // Only validate the form if we have collected all of the user input and are
...@@ -218,9 +224,10 @@ function authorize_filetransfer_form_validate($form, &$form_state) { ...@@ -218,9 +224,10 @@ function authorize_filetransfer_form_validate($form, &$form_state) {
} }
/** /**
* 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;
...@@ -280,7 +287,7 @@ function authorize_filetransfer_form_submit($form, &$form_state) { ...@@ -280,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.
...@@ -298,12 +305,13 @@ function authorize_run_operation($filetransfer) { ...@@ -298,12 +305,13 @@ 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.
......
<?php <?php
/** /**
* @file * @file
* Batch processing API for processes to run in multiple HTTP requests. * Batch processing API for processes to run in multiple HTTP requests.
...@@ -21,6 +20,7 @@ ...@@ -21,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.
*/ */
...@@ -36,7 +36,7 @@ function batch_load($id) { ...@@ -36,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()
*/ */
...@@ -94,7 +94,7 @@ function _batch_page() { ...@@ -94,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
...@@ -110,7 +110,7 @@ function _batch_start() { ...@@ -110,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
...@@ -144,7 +144,7 @@ function _batch_progress_page_js() { ...@@ -144,7 +144,7 @@ function _batch_progress_page_js() {
} }
/** /**
* 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()
...@@ -164,7 +164,7 @@ function _batch_do() { ...@@ -164,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()
*/ */
...@@ -228,7 +228,7 @@ function _batch_progress_page_nojs() { ...@@ -228,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
...@@ -370,7 +370,7 @@ function _batch_process() { ...@@ -370,7 +370,7 @@ 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.
...@@ -379,11 +379,14 @@ function _batch_process() { ...@@ -379,11 +379,14 @@ function _batch_process() {
* rather than an integer in the case of a multi-step operation that is not * 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 * yet complete; in that case, the fractional part of $current represents the
* fraction of the operation that has been completed. * 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) {
...@@ -410,7 +413,7 @@ function _batch_api_percentage($total, $current) { ...@@ -410,7 +413,7 @@ function _batch_api_percentage($total, $current) {
} }
/** /**
* 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();
...@@ -418,7 +421,7 @@ function &_batch_current_set() { ...@@ -418,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
...@@ -442,7 +445,7 @@ function _batch_next_set() { ...@@ -442,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.
...@@ -457,10 +460,10 @@ function _batch_finished() { ...@@ -457,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));
} }
} }
} }
...@@ -521,7 +524,10 @@ function _batch_finished() { ...@@ -521,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()) {
...@@ -531,4 +537,3 @@ function _batch_shutdown() { ...@@ -531,4 +537,3 @@ function _batch_shutdown() {
->execute(); ->execute();
} }
} }
<?php <?php
/** /**
* @file * @file
* Queue handlers used by the Batch API. * Queue handlers used by the Batch API.
* *
* Those implementations: * These implementations:
* - ensure FIFO ordering, * - Ensure FIFO ordering.
* - let an item be repeatedly claimed until it is actually deleted (no notion * - Allow an item to be repeatedly claimed until it is actually deleted (no
* of lease time or 'expire' date), to allow multipass operations. * notion of lease time or 'expire' date), to allow multipass operations.
*/ */
/** /**
* Batch queue implementation. * Defines a batch queue.
* *
* Stale items from failed batches are cleaned from the {queue} table on cron * Stale items from failed batches are cleaned from the {queue} table on cron
* using the 'created' date. * using the 'created' date.
*/ */
class BatchQueue extends SystemQueue { class BatchQueue extends SystemQueue {
/**
* Overrides SystemQueue::claimItem().
*
* Unlike SystemQueue::claimItem(), this method provides a default lease
* time of 0 (no expiration) instead of 30. This allows the item to be
* claimed repeatedly until it is deleted.
*/
public function claimItem($lease_time = 0) { public function claimItem($lease_time = 0) {
$item = db_query_range('SELECT data, item_id FROM {queue} q WHERE name = :name ORDER BY item_id ASC', 0, 1, array(':name' => $this->name))->fetchObject(); $item = db_query_range('SELECT data, item_id FROM {queue} q WHERE name = :name ORDER BY item_id ASC', 0, 1, array(':name' => $this->name))->fetchObject();
if ($item) { if ($item) {
...@@ -29,9 +35,9 @@ public function claimItem($lease_time = 0) { ...@@ -29,9 +35,9 @@ public function claimItem($lease_time = 0) {
} }
/** /**
* Retrieve all remaining items in the queue. * Retrieves all remaining items in the queue.
* *
* This is specific to Batch API and is not part of the DrupalQueueInterface, * This is specific to Batch API and is not part of the DrupalQueueInterface.
*/ */
public function getAllItems() { public function getAllItems() {
$result = array(); $result = array();
...@@ -44,10 +50,17 @@ public function getAllItems() { ...@@ -44,10 +50,17 @@ public function getAllItems() {
} }
/** /**
* Batch queue implementation used for non-progressive batches. * Defines a batch queue for non-progressive batches.
*/ */
class BatchMemoryQueue extends MemoryQueue { class BatchMemoryQueue extends MemoryQueue {
/**
* Overrides MemoryQueue::claimItem().
*
* Unlike MemoryQueue::claimItem(), this method provides a default lease
* time of 0 (no expiration) instead of 30. This allows the item to be
* claimed repeatedly until it is deleted.
*/
public function claimItem($lease_time = 0) { public function claimItem($lease_time = 0) {
if (!empty($this->queue)) { if (!empty($this->queue)) {
reset($this->queue); reset($this->queue);
...@@ -57,9 +70,9 @@ public function claimItem($lease_time = 0) { ...@@ -57,9 +70,9 @@ public function claimItem($lease_time = 0) {
} }
/** /**
* Retrieve all remaining items in the queue. * Retrieves all remaining items in the queue.
* *
* This is specific to Batch API and is not part of the DrupalQueueInterface, * This is specific to Batch API and is not part of the DrupalQueueInterface.
*/ */
public function getAllItems() { public function getAllItems() {
$result = array(); $result = array();
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.