Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3310c6fad6 | ||
|
|
7580376050 | ||
|
|
acaa381d3d | ||
|
|
c3011cef61 | ||
|
|
10de06dd70 | ||
|
|
572f88b950 | ||
|
|
cb791f03ff | ||
|
|
33ce5d0e40 | ||
|
|
8e478340a2 | ||
|
|
78fa0756a9 | ||
|
|
176b1c05d9 | ||
|
|
acbf965c77 | ||
|
|
bd98c3d7f6 | ||
|
|
1c56076189 | ||
|
|
e0ab0fd0d5 | ||
|
|
b58a00a4c8 | ||
|
|
4d81ea318d | ||
|
|
77cb87b49d | ||
|
|
5203118606 | ||
|
|
9faad4a27d | ||
|
|
32e4448773 | ||
|
|
e539e701f8 | ||
|
|
db5f70501a | ||
|
|
f1c9615e4a | ||
|
|
84542b241d | ||
|
|
e99ac67b73 | ||
|
|
5a4cadabf6 | ||
|
|
5658794f17 | ||
|
|
d5097a4bc6 | ||
|
|
661765bde9 | ||
|
|
fde4f26165 | ||
|
|
8763bf01dd | ||
|
|
49fb38b169 | ||
|
|
de022d62e2 | ||
|
|
d9d092295b | ||
|
|
8c47736b71 | ||
|
|
1aa3c4e9eb | ||
|
|
1f662a2b40 | ||
|
|
83cf488d4a | ||
|
|
1a145b8470 | ||
|
|
8c09d74e68 | ||
|
|
8e432ea544 | ||
|
|
2d4301ad40 | ||
|
|
662012976d | ||
|
|
cc526dd563 | ||
|
|
6d0af35191 | ||
|
|
6a94814eaa | ||
|
|
1b6b74ea40 |
@@ -71,6 +71,18 @@ DirectoryIndex index.php index.html index.htm
|
|||||||
# downloaded.
|
# downloaded.
|
||||||
RewriteRule "(^|/)\." - [F]
|
RewriteRule "(^|/)\." - [F]
|
||||||
|
|
||||||
|
# custom
|
||||||
|
RewriteCond %{HTTP_HOST} ^basebeta\.materio\.com [OR]
|
||||||
|
RewriteCond %{HTTP_HOST} ^materio\.com [OR]
|
||||||
|
RewriteCond %{HTTP_HOST} ^www\.materio\.fr [OR]
|
||||||
|
RewriteCond %{HTTP_HOST} ^materio\.fr [OR]
|
||||||
|
RewriteCond %{HTTP_HOST} ^www\.materio\.net [OR]
|
||||||
|
RewriteCond %{HTTP_HOST} ^materio\.net [OR]
|
||||||
|
RewriteCond %{HTTP_HOST} ^www\.materio\.eu [OR]
|
||||||
|
RewriteCond %{HTTP_HOST} ^materio\.eu [NC]
|
||||||
|
RewriteRule ^ http://www.materio.com%{REQUEST_URI} [L,R=301]
|
||||||
|
|
||||||
|
|
||||||
# If your site can be accessed both with and without the 'www.' prefix, you
|
# If your site can be accessed both with and without the 'www.' prefix, you
|
||||||
# can use one of the following settings to redirect users to your preferred
|
# can use one of the following settings to redirect users to your preferred
|
||||||
# URL, either WITH or WITHOUT the 'www.' prefix. Choose ONLY one option:
|
# URL, either WITH or WITHOUT the 'www.' prefix. Choose ONLY one option:
|
||||||
@@ -104,6 +116,24 @@ DirectoryIndex index.php index.html index.htm
|
|||||||
RewriteCond %{REQUEST_URI} !=/favicon.ico
|
RewriteCond %{REQUEST_URI} !=/favicon.ico
|
||||||
RewriteRule ^ index.php [L]
|
RewriteRule ^ index.php [L]
|
||||||
|
|
||||||
|
## local
|
||||||
|
# RewriteCond %{REMOTE_ADDR} !^127\.0\.0\.1
|
||||||
|
## maison quentin
|
||||||
|
# RewriteCond %{REMOTE_ADDR} !^86\.68\.188\.175
|
||||||
|
## materio
|
||||||
|
# RewriteCond %{REMOTE_ADDR} !^212\.198\.136\.215
|
||||||
|
## maison bach
|
||||||
|
# RewriteCond %{REMOTE_ADDR} !^82\.230\.62\.145
|
||||||
|
# RewriteRule !maintenance http://www.materio.com/maintenance [L,R=302,E=nocache:1]
|
||||||
|
|
||||||
|
## http://mark.koli.ch/2010/12/set-cache-control-and-expires-headers-on-a-redirect-with-mod-rewrite.html
|
||||||
|
## Set the response header if the "nocache" environment variable is set
|
||||||
|
## in the RewriteRule above.
|
||||||
|
# Header always set Cache-Control "no-store, no-cache, must-revalidate" env=nocache
|
||||||
|
## Set Expires too ...
|
||||||
|
# Header always set Expires "Thu, 01 Jan 1970 00:00:00 GMT" env=nocache
|
||||||
|
|
||||||
|
|
||||||
# Rules to correctly serve gzip compressed CSS and JS files.
|
# Rules to correctly serve gzip compressed CSS and JS files.
|
||||||
# Requires both mod_rewrite and mod_headers to be enabled.
|
# Requires both mod_rewrite and mod_headers to be enabled.
|
||||||
<IfModule mod_headers.c>
|
<IfModule mod_headers.c>
|
||||||
|
|||||||
@@ -1,3 +1,244 @@
|
|||||||
|
|
||||||
|
Drupal 7.28, 2014-05-08
|
||||||
|
-----------------------
|
||||||
|
- Fixed a regression introduced in Drupal 7.27 that caused JavaScript to break
|
||||||
|
on older browsers (such as Internet Explorer 8 and earlier) when Ajax was
|
||||||
|
used.
|
||||||
|
- Increased the timeout used by the Update Manager module when it fetches data
|
||||||
|
from drupal.org (from 5 seconds to 30 seconds), to work around a problem
|
||||||
|
which causes incomplete information about security updates to be presented to
|
||||||
|
site administrators. This fix may lead to a performance slowdown on the
|
||||||
|
Update Manager administration pages, when installing Drupal distributions,
|
||||||
|
and (for sites that use the automated cron feature) on occasional page loads
|
||||||
|
by site visitors.
|
||||||
|
- Fixed the behavior of the token system's "[node:summary]" token when the body
|
||||||
|
field does not have a manual summary.
|
||||||
|
- Changed the behavior of db_query_temporary() so that it works on SELECT
|
||||||
|
queries even when they have leading comments/whitespace. A side effect of
|
||||||
|
this fix is that db_query_temporary() will now fail with an error if it is
|
||||||
|
ever used on non-SELECT queries.
|
||||||
|
- Added a "node_admin_filter" tag to the database query used to build the list
|
||||||
|
of nodes on the content administration page, to make it easier to alter.
|
||||||
|
- Made the cron queue system log any exceptions that are thrown while an item
|
||||||
|
in the queue is being processed, rather than stopping the entire PHP request.
|
||||||
|
- Improved screen reader support by adding an aria-live HTML attribute to file
|
||||||
|
upload fields when there is an error uploading the file (minor markup
|
||||||
|
change).
|
||||||
|
- Made the pager on the Tracker module listing pages show the same number of
|
||||||
|
items as other pagers throughout Drupal core (minor UI change).
|
||||||
|
- Fixed a bug which caused caches not to be properly cleared when a file entity
|
||||||
|
was saved or deleted.
|
||||||
|
- Added several missing countries to the default list returned by
|
||||||
|
country_get_list() (string change).
|
||||||
|
- Replaced the term "weight" with "influence" in the content ranking settings
|
||||||
|
for search, and added help text for administrators (string change).
|
||||||
|
- Fixed untranslatable text strings in the administrative interface for the
|
||||||
|
"Crop" effect provided by the Image module (minor string change).
|
||||||
|
- Fixed a bug in the Taxonomy module update function introduced in Drupal 7.26
|
||||||
|
that caused memory and CPU problems on sites with very large numbers of
|
||||||
|
unpublished nodes.
|
||||||
|
- Numerous small bug fixes.
|
||||||
|
- Numerous API documentation improvements.
|
||||||
|
- Additional automated test coverage.
|
||||||
|
|
||||||
|
Drupal 7.27, 2014-04-16
|
||||||
|
----------------------
|
||||||
|
- Fixed security issues (information disclosure). See SA-CORE-2014-002.
|
||||||
|
|
||||||
|
Drupal 7.26, 2014-01-15
|
||||||
|
----------------------
|
||||||
|
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2014-001.
|
||||||
|
|
||||||
|
Drupal 7.25, 2014-01-02
|
||||||
|
-----------------------
|
||||||
|
- Fixed a bug in node_save() which prevented the saved node from being updated
|
||||||
|
in hook_node_insert() and other similar hooks.
|
||||||
|
- Added a meta tag to install.php to prevent it from being indexed by search
|
||||||
|
engines even when Drupal is installed in a subfolder (minor markup change).
|
||||||
|
- Fixed a bug in the database API that caused frequent deadlock errors when
|
||||||
|
running merge queries on some servers.
|
||||||
|
- Performance improvement: Prevented block rehashing from writing blocks to the
|
||||||
|
database on every cache clear and cron run when the blocks have not changed.
|
||||||
|
This fix results in an extra 'saved' key which is added and set to TRUE for
|
||||||
|
each block returned by _block_rehash() that actually is saved to the database
|
||||||
|
(data structure change).
|
||||||
|
- Added an optional 'skip on cron' parameter to hook_cron_queue_info() to allow
|
||||||
|
queues to avoid being automatically processed on cron runs (API addition).
|
||||||
|
- Fixed a bug which caused hook_block_view_MODULE_DELTA_alter() to never be
|
||||||
|
invoked if the block delta had a hyphen in it. To implement the hook when the
|
||||||
|
block delta has a hyphen, modules should now replace hyphens with underscores
|
||||||
|
when constructing the function name for the hook implementation.
|
||||||
|
- Fixed a bug which caused cached pages to sometimes be sent to the browser
|
||||||
|
with incorrect compression. The fix adds a new 'page_compressed' key to the
|
||||||
|
$cache->data array returned by drupal_page_get_cache() (minor data structure
|
||||||
|
change).
|
||||||
|
- Fixed broken tests on PHP 5.5.
|
||||||
|
- Made the File and Image modules more robust when saving entities that have
|
||||||
|
deleted files attached. The code in file_field_presave() will now remove the
|
||||||
|
record of the deleted file from the entity before saving (minor data
|
||||||
|
structure change).
|
||||||
|
- Standardized menu callback functions throughout Drupal core to return
|
||||||
|
MENU_NOT_FOUND and MENU_ACCESS_DENIED rather than printing their own "page
|
||||||
|
not found" or "access denied" pages (minor API change in the return value of
|
||||||
|
these functions under some circumstances).
|
||||||
|
- Fixed a bug in which caches were not properly cleared when a node was deleted
|
||||||
|
via the administrative interface.
|
||||||
|
- Changed the Bartik theme to render content contained in <pre>, <code> and
|
||||||
|
similar tags in a larger font size, so it is easier to read.
|
||||||
|
- Fixed a bug in the Search module that caused exceptions to be thrown during
|
||||||
|
searches if the server was not configured to represent decimal points as a
|
||||||
|
period.
|
||||||
|
- Fixed a regression in the Image module that made image_style_url() not work
|
||||||
|
when a relative path (rather than a complete file URI) was passed to it.
|
||||||
|
- Added an optional feature to the Statistics module to allow node views to be
|
||||||
|
tracked by Ajax requests rather than during the server-side generation of the
|
||||||
|
page. This allows the node counter to work on sites that use external page
|
||||||
|
caches (string change and new administrative option:
|
||||||
|
https://drupal.org/node/2164069).
|
||||||
|
- Added a link to the drupal.org documentation page for cron to the Cron
|
||||||
|
settings page (string change).
|
||||||
|
- Added a 'drupal_anonymous_user_object' variable to allow the anonymous user
|
||||||
|
object returned by drupal_anonymous_user() to be overridden with a classed
|
||||||
|
object (API addition).
|
||||||
|
- Changed the database API to allow inserts based on a SELECT * query to work
|
||||||
|
correctly.
|
||||||
|
- Changed the database schema of the {file_managed} table to allow Drupal to
|
||||||
|
manage files larger than 4 GB.
|
||||||
|
- Changed the File module's hook_field_load() implementation to prevent file
|
||||||
|
entity properties which have the same name as file or image field properties
|
||||||
|
from overwriting the field properties (minor API change).
|
||||||
|
- Numerous small bug fixes.
|
||||||
|
- Numerous API documentation improvements.
|
||||||
|
- Additional automated test coverage.
|
||||||
|
|
||||||
|
Drupal 7.24, 2013-11-20
|
||||||
|
----------------------
|
||||||
|
- Fixed security issues (multiple vulnerabilities), see SA-CORE-2013-003.
|
||||||
|
|
||||||
|
Drupal 7.23, 2013-08-07
|
||||||
|
-----------------------
|
||||||
|
- Fixed a fatal error on PostgreSQL databases when updating the Taxonomy module
|
||||||
|
from Drupal 6 to Drupal 7.
|
||||||
|
- Fixed the default ordering of CSS files for sites using right-to-left
|
||||||
|
languages, to consistently place the right-to-left override file immediately
|
||||||
|
after the CSS it is overriding (API change: https://drupal.org/node/2058463).
|
||||||
|
- Added a drupal_check_memory_limit() API function to allow the memory limit to
|
||||||
|
be checked consistently (API addition).
|
||||||
|
- Changed the default web.config file for IIS servers to allow favicon.ico
|
||||||
|
files which are present in the filesystem to be accessed.
|
||||||
|
- Fixed inconsistent support for the 'tel' protocol in Drupal's URL filtering
|
||||||
|
functions.
|
||||||
|
- Performance improvement: Allowed all hooks to be included in the
|
||||||
|
module_implements() cache, even those that are only invoked on HTTP POST
|
||||||
|
requests.
|
||||||
|
- Made the database system replace truncate queries with delete queries when
|
||||||
|
inside a transaction, to fix issues with PostgreSQL and other databases.
|
||||||
|
- Fixed a bug which caused nested contextual links to display improperly.
|
||||||
|
- Fixed a bug which prevented cached image derivatives from being flushed for
|
||||||
|
private files and other non-default file schemes.
|
||||||
|
- Fixed drupal_render() to always return an empty string when there is no
|
||||||
|
output, rather than sometimes returning NULL (minor API change).
|
||||||
|
- Added protection to cache_clear_all() to ensure that non-cache tables cannot
|
||||||
|
be truncated (API addition: a new isValidBin() method has been added to the
|
||||||
|
default database cache implementation).
|
||||||
|
- Changed the default .htaccess file to support HTTP authorization in CGI
|
||||||
|
environments.
|
||||||
|
- Changed the password reset form to pre-fill the username when requested via a
|
||||||
|
URL query parameter, and used this in the error message that appears after a
|
||||||
|
failed login attempt (minor data structure and behavior change).
|
||||||
|
- Fixed broken support for foreign keys in the field API.
|
||||||
|
- Fixed "No active batch" error when a user cancels their own account.
|
||||||
|
- Added a description to the "access content overview" permission on the
|
||||||
|
permissions page (string change).
|
||||||
|
- Added a drupal_array_diff_assoc_recursive() function to allow associative
|
||||||
|
arrays to be compared recursively (API addition).
|
||||||
|
- Added human-readable labels to image styles, in addition to the existing
|
||||||
|
machine-readable name (API change: https://drupal.org/node/2058503).
|
||||||
|
- Moved the drupal_get_hash_salt() function to bootstrap.inc and used it in
|
||||||
|
additional places in the code, for added security in the case where there is
|
||||||
|
no hash salt in settings.php.
|
||||||
|
- Fixed a regression in Drupal 7.22 that caused internal server errors for
|
||||||
|
sites running on very old Apache 1.x web servers.
|
||||||
|
- Numerous small bug fixes.
|
||||||
|
- Numerous API documentation improvements.
|
||||||
|
- Additional automated test coverage.
|
||||||
|
|
||||||
|
Drupal 7.22, 2013-04-03
|
||||||
|
-----------------------
|
||||||
|
- Allowed the drupal_http_request() function to be overridden so that
|
||||||
|
additional HTTP request capabilities can be added by contributed modules.
|
||||||
|
- Changed the Simpletest module to allow PSR-0 test classes to be used in
|
||||||
|
Drupal 7.
|
||||||
|
- Removed an unnecessary "Content-Disposition" header from private file
|
||||||
|
downloads; it prevented many private files from being viewed inline in a web
|
||||||
|
browser.
|
||||||
|
- Changed various field API functions to allow them to optionally act on a
|
||||||
|
single field within an entity (API addition: http://drupal.org/node/1825844).
|
||||||
|
- Fixed a bug which prevented Drupal's file transfer functionality from working
|
||||||
|
on some PHP 5.4 systems.
|
||||||
|
- Fixed incorrect log message when theme() is called for a theme hook that does
|
||||||
|
not exist (minor string change).
|
||||||
|
- Fixed Drupal's token-replacement system to allow spaces in the token value.
|
||||||
|
- Changed the default behavior after a user creates a node they do not have
|
||||||
|
access to view. The user will now be redirected to the front page rather than
|
||||||
|
an access denied page.
|
||||||
|
- Fixed a bug which prevented empty HTTP headers (such as "0") from being set.
|
||||||
|
(Minor behavior change: Callers of drupal_add_http_header() must now set
|
||||||
|
FALSE explicitly to prevent a header from being sent at all; this was already
|
||||||
|
indicated in the function's documentation.)
|
||||||
|
- Fixed OpenID errors when more than one module implements hook_openid(). The
|
||||||
|
behavior is now changed so that if more than one module tries to set the same
|
||||||
|
parameter, the last module's change takes effect.
|
||||||
|
- Fixed a serious documentation bug: The $name variable in the
|
||||||
|
taxonomy-term.tpl.php theme template was incorrectly documented as being
|
||||||
|
sanitized when in fact it is not.
|
||||||
|
- Fixed a bug which prevented Drupal 6 to Drupal 7 upgrades on sites which had
|
||||||
|
duplicate permission names in the User module's database tables.
|
||||||
|
- Added an empty "datatype" attribute to taxonomy term and username links to
|
||||||
|
make the RDFa markup upward compatible with RDFa 1.1 (minor markup addition).
|
||||||
|
- Fixed a bug which caused the denial-of-service protection added in Drupal
|
||||||
|
7.20 to break certain valid image URLs that had an extra slash in them.
|
||||||
|
- Fixed a bug with update queries in the SQLite database driver that prevented
|
||||||
|
Drupal from being installed with SQLite on PHP 5.4.
|
||||||
|
- Fixed enforced dependencies errors updating to recent versions of Drupal 7 on
|
||||||
|
certain non-MySQL databases.
|
||||||
|
- Refactored the Field module's caching behavior to obtain large improvements
|
||||||
|
in memory usage for sites with many fields and instances (API addition:
|
||||||
|
http://drupal.org/node/1915646).
|
||||||
|
- Fixed entity argument not being passed to implementations of
|
||||||
|
hook_file_download_access_alter(). The fix adds an additional context
|
||||||
|
parameter that can be passed when calling drupal_alter() for any hook (API
|
||||||
|
change: http://drupal.org/node/1882722).
|
||||||
|
- Fixed broken support for translatable comment fields (API change:
|
||||||
|
http://drupal.org/node/1874724).
|
||||||
|
- Added an assertThemeOutput() method to Simpletest to allow tests to check
|
||||||
|
that themed output matches an expected HTML string (API addition).
|
||||||
|
- Added a link to "Install another module" after a module has been successfully
|
||||||
|
downloaded via the Update Manager (UI change).
|
||||||
|
- Added an optional "exclusive" flag to installation profile .info files which
|
||||||
|
allows Drupal distributions to force a profile to be selected during
|
||||||
|
installation (API addition: http://drupal.org/node/1961012).
|
||||||
|
- Fixed a bug which caused the database API to not properly close database
|
||||||
|
connections.
|
||||||
|
- Added a link to the URL for running cron from outside the site to the Cron
|
||||||
|
settings page (UI change).
|
||||||
|
- Fixed a bug which prevented image styles from being reverted on PHP 5.4.
|
||||||
|
- Made the default .htaccess rules protocol sensitive to improve security for
|
||||||
|
sites which use HTTPS and redirect between "www" and non-"www" versions of
|
||||||
|
the page.
|
||||||
|
- Numerous small bug fixes.
|
||||||
|
- Numerous API documentation improvements.
|
||||||
|
- Additional automated test coverage.
|
||||||
|
|
||||||
|
Drupal 7.21, 2013-03-06
|
||||||
|
-----------------------
|
||||||
|
- Allowed sites using the 'image_allow_insecure_derivatives' variable to still
|
||||||
|
have partial protection from the security issues fixed in Drupal 7.20.
|
||||||
|
|
||||||
|
Drupal 7.20, 2013-02-20
|
||||||
|
-----------------------
|
||||||
|
- Fixed security issues (denial of service). See SA-CORE-2013-002.
|
||||||
|
|
||||||
Drupal 7.19, 2013-01-16
|
Drupal 7.19, 2013-01-16
|
||||||
-----------------------
|
-----------------------
|
||||||
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2013-001.
|
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2013-001.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
All Drupal code is Copyright 2001 - 2012 by the original authors.
|
All Drupal code is Copyright 2001 - 2013 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
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
|
|
||||||
CREATE THE MySQL DATABASE
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
This step is only necessary if you don't already have a database set up (e.g.,
|
|
||||||
by your host). In the following examples, 'username' is an example MySQL user
|
|
||||||
which has the CREATE and GRANT privileges. Use the appropriate user name for
|
|
||||||
your system.
|
|
||||||
|
|
||||||
First, you must create a new database for your Drupal site (here, 'databasename'
|
|
||||||
is the name of the new database):
|
|
||||||
|
|
||||||
mysqladmin -u username -p create databasename
|
|
||||||
|
|
||||||
MySQL will prompt for the 'username' database password and then create the
|
|
||||||
initial database files. Next you must log in and set the access database rights:
|
|
||||||
|
|
||||||
mysql -u username -p
|
|
||||||
|
|
||||||
Again, you will be asked for the 'username' database password. At the MySQL
|
|
||||||
prompt, enter the following command:
|
|
||||||
|
|
||||||
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER
|
|
||||||
ON databasename.*
|
|
||||||
TO 'username'@'localhost' IDENTIFIED BY 'password';
|
|
||||||
|
|
||||||
where
|
|
||||||
|
|
||||||
'databasename' is the name of your database
|
|
||||||
'username@localhost' is the username of your MySQL account
|
|
||||||
'password' is the password required for that username
|
|
||||||
|
|
||||||
Note: Unless your database user has all of the privileges listed above, you will
|
|
||||||
not be able to run Drupal.
|
|
||||||
|
|
||||||
If successful, MySQL will reply with:
|
|
||||||
|
|
||||||
Query OK, 0 rows affected
|
|
||||||
|
|
||||||
If the InnoDB storage engine is available, it will be used for all database
|
|
||||||
tables. InnoDB provides features over MyISAM such as transaction support,
|
|
||||||
row-level locks, and consistent non-locking reads.
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
|
|
||||||
CREATE THE PostgreSQL DATABASE
|
|
||||||
------------------------------
|
|
||||||
|
|
||||||
Note that the database must be created with UTF-8 (Unicode) encoding.
|
|
||||||
|
|
||||||
1. CREATE DATABASE USER
|
|
||||||
|
|
||||||
This step is only necessary if you don't already have a user set up (e.g., by
|
|
||||||
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 password
|
|
||||||
for that user:
|
|
||||||
|
|
||||||
createuser --pwprompt --encrypted --no-createrole --no-createdb username
|
|
||||||
|
|
||||||
If there are no errors, then the command was successful.
|
|
||||||
|
|
||||||
2. CREATE DRUPAL DATABASE
|
|
||||||
|
|
||||||
This step is only necessary if you don't already have a database set up
|
|
||||||
(e.g., by your host) or want to create a new database for use with Drupal
|
|
||||||
only. The following command creates a new database named 'databasename',
|
|
||||||
which is owned by the previously created 'username':
|
|
||||||
|
|
||||||
createdb --encoding=UTF8 --owner=username databasename
|
|
||||||
|
|
||||||
If there are no errors, then the command was successful.
|
|
||||||
|
|
||||||
3. CREATE SCHEMA OR SCHEMAS (Optional advanced step)
|
|
||||||
|
|
||||||
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
|
|
||||||
inside settings.php to define a schema for Drupal to run inside of, or
|
|
||||||
specify tables that are shared inside of a separate schema. Drupal will not
|
|
||||||
create schemas for you. In fact, the user that Drupal runs as should not be
|
|
||||||
allowed to do this. You'll need to execute the SQL below as a superuser,
|
|
||||||
replace 'username' with the username that Drupal uses to connect to
|
|
||||||
PostgreSQL, and replace 'schema_name' with a schema name you wish to use,
|
|
||||||
such as 'shared':
|
|
||||||
|
|
||||||
CREATE SCHEMA schema_name AUTHORIZATION username;
|
|
||||||
|
|
||||||
Do this for as many schemas as you need. See default.settings.php for
|
|
||||||
instructions on how to set which tables use which schemas.
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
|
|
||||||
SQLITE REQUIREMENTS
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
To use SQLite with your Drupal installation, the following requirements must be
|
|
||||||
met: Server has PHP 5.2 or later with PDO, and the PDO SQLite driver must be
|
|
||||||
enabled.
|
|
||||||
|
|
||||||
SQLITE DATABASE CREATION
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
The Drupal installer will create the SQLite database for you. The only
|
|
||||||
requirement is that the installer must have write permissions to the directory
|
|
||||||
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 file" field, you must
|
|
||||||
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
|
|
||||||
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
|
|
||||||
following in your "Database file" field:
|
|
||||||
|
|
||||||
sites/default/files/.ht.sqlite
|
|
||||||
|
|
||||||
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.
|
|
||||||
If not, please consult the documentation of your webserver on how to protect a
|
|
||||||
file from downloading.
|
|
||||||
@@ -1,398 +0,0 @@
|
|||||||
|
|
||||||
CONTENTS OF THIS FILE
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
* Requirements and notes
|
|
||||||
* Optional server requirements
|
|
||||||
* Installation
|
|
||||||
* Building and customizing your site
|
|
||||||
* Multisite configuration
|
|
||||||
* More information
|
|
||||||
|
|
||||||
REQUIREMENTS AND NOTES
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
Drupal requires:
|
|
||||||
|
|
||||||
- A web server. Apache (version 2.0 or greater) is recommended.
|
|
||||||
- PHP 5.2.4 (or greater) (http://www.php.net/).
|
|
||||||
- One of the following databases:
|
|
||||||
- MySQL 5.0.15 (or greater) (http://www.mysql.com/).
|
|
||||||
- MariaDB 5.1.44 (or greater) (http://mariadb.org/). MariaDB is a fully
|
|
||||||
compatible drop-in replacement for MySQL.
|
|
||||||
- PostgreSQL 8.3 (or greater) (http://www.postgresql.org/).
|
|
||||||
- SQLite 3.4.2 (or greater) (http://www.sqlite.org/).
|
|
||||||
|
|
||||||
For more detailed information about Drupal requirements, including a list of
|
|
||||||
PHP extensions and configurations that are required, see "System requirements"
|
|
||||||
(http://drupal.org/requirements) in the Drupal.org online documentation.
|
|
||||||
|
|
||||||
For detailed information on how to configure a test server environment using a
|
|
||||||
variety of operating systems and web servers, see "Local server setup"
|
|
||||||
(http://drupal.org/node/157602) in the Drupal.org online documentation.
|
|
||||||
|
|
||||||
Note that all directories mentioned in this document are always relative to the
|
|
||||||
directory of your Drupal installation, and commands are meant to be run from
|
|
||||||
this directory (except for the initial commands that create that directory).
|
|
||||||
|
|
||||||
OPTIONAL SERVER REQUIREMENTS
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
- If you want to use Drupal's "Clean URLs" feature on an Apache web server, you
|
|
||||||
will need the mod_rewrite module and the ability to use local .htaccess
|
|
||||||
files. For Clean URLs support on IIS, see "Clean URLs with IIS"
|
|
||||||
(http://drupal.org/node/3854) in the Drupal.org online documentation.
|
|
||||||
|
|
||||||
- If you plan to use XML-based services such as RSS aggregation, you will need
|
|
||||||
PHP's XML extension. This extension is enabled by default on most PHP
|
|
||||||
installations.
|
|
||||||
|
|
||||||
- To serve gzip compressed CSS and JS files on an Apache web server, you will
|
|
||||||
need the mod_headers module and the ability to use local .htaccess files.
|
|
||||||
|
|
||||||
- Some Drupal functionality (e.g., checking whether Drupal and contributed
|
|
||||||
modules need updates, RSS aggregation, etc.) require that the web server be
|
|
||||||
able to go out to the web and download information. If you want to use this
|
|
||||||
functionality, you need to verify that your hosting provider or server
|
|
||||||
configuration allows the web server to initiate outbound connections. Most web
|
|
||||||
hosting setups allow this.
|
|
||||||
|
|
||||||
INSTALLATION
|
|
||||||
------------
|
|
||||||
|
|
||||||
1. Download and extract Drupal.
|
|
||||||
|
|
||||||
You can obtain the latest Drupal release from http://drupal.org -- the files
|
|
||||||
are available in .tar.gz and .zip formats and can be extracted using most
|
|
||||||
compression tools.
|
|
||||||
|
|
||||||
To download and extract the files, on a typical Unix/Linux command line, use
|
|
||||||
the following commands (assuming you want version x.y of Drupal in .tar.gz
|
|
||||||
format):
|
|
||||||
|
|
||||||
wget http://drupal.org/files/projects/drupal-x.y.tar.gz
|
|
||||||
tar -zxvf drupal-x.y.tar.gz
|
|
||||||
|
|
||||||
This will create a new directory drupal-x.y/ containing all Drupal files and
|
|
||||||
directories. Then, to move the contents of that directory into a directory
|
|
||||||
within your web server's document root or your public HTML directory,
|
|
||||||
continue with this command:
|
|
||||||
|
|
||||||
mv drupal-x.y/* drupal-x.y/.htaccess /path/to/your/installation
|
|
||||||
|
|
||||||
2. Optionally, download a translation.
|
|
||||||
|
|
||||||
By default, Drupal is installed in English, and further languages may be
|
|
||||||
installed later. If you prefer to install Drupal in another language
|
|
||||||
initially:
|
|
||||||
|
|
||||||
- Download a translation file for the correct Drupal version and language
|
|
||||||
from the translation server: http://localize.drupal.org/translate/downloads
|
|
||||||
|
|
||||||
- Place the file into your installation profile's translations directory.
|
|
||||||
For instance, if you are using the Standard installation profile,
|
|
||||||
move the .po file into the directory:
|
|
||||||
|
|
||||||
profiles/standard/translations/
|
|
||||||
|
|
||||||
For detailed instructions, visit http://drupal.org/localize
|
|
||||||
|
|
||||||
3. Create the Drupal database.
|
|
||||||
|
|
||||||
Because Drupal stores all site information in a database, you must create
|
|
||||||
this database in order to install Drupal, and grant Drupal certain database
|
|
||||||
privileges (such as the ability to create tables). For details, consult
|
|
||||||
INSTALL.mysql.txt, INSTALL.pgsql.txt, or INSTALL.sqlite.txt. You may also
|
|
||||||
need to consult your web hosting provider for instructions specific to your
|
|
||||||
web host.
|
|
||||||
|
|
||||||
Take note of the username, password, database name, and hostname as you
|
|
||||||
create the database. You will enter this information during the install.
|
|
||||||
|
|
||||||
4. Run the install script.
|
|
||||||
|
|
||||||
To run the install script, point your browser to the base URL of your
|
|
||||||
website (e.g., http://www.example.com).
|
|
||||||
|
|
||||||
You will be guided through several screens to set up the database, add the
|
|
||||||
site maintenance account (the first user, also known as user/1), and provide
|
|
||||||
basic web site settings.
|
|
||||||
|
|
||||||
During installation, several files and directories need to be created, which
|
|
||||||
the install script will try to do automatically. However, on some hosting
|
|
||||||
environments, manual steps are required, and the install script will tell
|
|
||||||
you that it cannot proceed until you fix certain issues. This is normal and
|
|
||||||
does not indicate a problem with your server.
|
|
||||||
|
|
||||||
The most common steps you may need to perform are:
|
|
||||||
|
|
||||||
a. Missing files directory.
|
|
||||||
|
|
||||||
The install script will attempt to create a file storage directory in
|
|
||||||
the default location at sites/default/files (the location of the files
|
|
||||||
directory may be changed after Drupal is installed).
|
|
||||||
|
|
||||||
If auto-creation fails, you can make it work by changing permissions on
|
|
||||||
the sites/default directory so that the web server can create the files
|
|
||||||
directory within it for you. (If you are creating a multisite
|
|
||||||
installation, substitute the correct sites directory for sites/default;
|
|
||||||
see the Multisite Configuration section of this file, below.)
|
|
||||||
|
|
||||||
For example, on a Unix/Linux command line, you can grant everyone
|
|
||||||
(including the web server) permission to write to the sites/default
|
|
||||||
directory with this command:
|
|
||||||
|
|
||||||
chmod a+w sites/default
|
|
||||||
|
|
||||||
Be sure to set the permissions back after the installation is finished!
|
|
||||||
Sample command:
|
|
||||||
|
|
||||||
chmod go-w sites/default
|
|
||||||
|
|
||||||
Alternatively, instead of allowing the web server to create the files
|
|
||||||
directory for you as described above, you can create it yourself. Sample
|
|
||||||
commands from a Unix/Linux command line:
|
|
||||||
|
|
||||||
mkdir sites/default/files
|
|
||||||
chmod a+w sites/default/files
|
|
||||||
|
|
||||||
b. Missing settings file.
|
|
||||||
|
|
||||||
Drupal will try to automatically create a settings.php configuration file,
|
|
||||||
which is normally in the directory sites/default (to avoid problems when
|
|
||||||
upgrading, Drupal is not packaged with this file). If auto-creation fails,
|
|
||||||
you will need to create this file yourself, using the file
|
|
||||||
sites/default/default.settings.php as a template.
|
|
||||||
|
|
||||||
For example, on a Unix/Linux command line, you can make a copy of the
|
|
||||||
default.settings.php file with the command:
|
|
||||||
|
|
||||||
cp sites/default/default.settings.php sites/default/settings.php
|
|
||||||
|
|
||||||
Next, grant write privileges to the file to everyone (including the web
|
|
||||||
server) with the command:
|
|
||||||
|
|
||||||
chmod a+w sites/default/settings.php
|
|
||||||
|
|
||||||
Be sure to set the permissions back after the installation is finished!
|
|
||||||
Sample command:
|
|
||||||
|
|
||||||
chmod go-w sites/default/settings.php
|
|
||||||
|
|
||||||
c. Write permissions after install.
|
|
||||||
|
|
||||||
The install script will attempt to write-protect the settings.php file and
|
|
||||||
the sites/default directory after saving your configuration. If this
|
|
||||||
fails, you will be notified, and you can do it manually. Sample commands
|
|
||||||
from a Unix/Linux command line:
|
|
||||||
|
|
||||||
chmod go-w sites/default/settings.php
|
|
||||||
chmod go-w sites/default
|
|
||||||
|
|
||||||
5. Verify that the site is working.
|
|
||||||
|
|
||||||
When the install script finishes, you will be logged in with the site
|
|
||||||
maintenance account on a "Welcome" page. If the default Drupal theme is not
|
|
||||||
displaying properly and links on the page result in "Page Not Found" errors,
|
|
||||||
you may be experiencing problems with clean URLs. Visit
|
|
||||||
http://drupal.org/getting-started/clean-urls to troubleshoot.
|
|
||||||
|
|
||||||
6. Change file system storage settings (optional).
|
|
||||||
|
|
||||||
The files directory created in step 4 is the default file system path used to
|
|
||||||
store all uploaded files, as well as some temporary files created by
|
|
||||||
Drupal. After installation, you can modify the file system path to store
|
|
||||||
uploaded files in a different location.
|
|
||||||
|
|
||||||
It is not necessary to modify this path, but you may wish to change it if:
|
|
||||||
|
|
||||||
- Your site runs multiple Drupal installations from a single codebase (modify
|
|
||||||
the file system path of each installation to a different directory so that
|
|
||||||
uploads do not overlap between installations).
|
|
||||||
|
|
||||||
- Your site runs on a number of web servers behind a load balancer or reverse
|
|
||||||
proxy (modify the file system path on each server to point to a shared file
|
|
||||||
repository).
|
|
||||||
|
|
||||||
- You want to restrict access to uploaded files.
|
|
||||||
|
|
||||||
To modify the file system path:
|
|
||||||
|
|
||||||
a. Ensure that the new location for the path exists and is writable by the
|
|
||||||
web server. For example, to create a new directory named uploads and grant
|
|
||||||
write permissions, use the following commands on a Unix/Linux command
|
|
||||||
line:
|
|
||||||
|
|
||||||
mkdir uploads
|
|
||||||
chmod a+w uploads
|
|
||||||
|
|
||||||
b. Navigate to Administration > Configuration > Media > File system, and
|
|
||||||
enter the desired path. Note that if you want to use private file storage,
|
|
||||||
you need to first enter the path for private files and save the
|
|
||||||
configuration, and then change the "Default download method" setting and
|
|
||||||
save again.
|
|
||||||
|
|
||||||
Changing the file system path after files have been uploaded may cause
|
|
||||||
unexpected problems on an existing site. If you modify the file system path
|
|
||||||
on an existing site, remember to copy all files from the original location
|
|
||||||
to the new location.
|
|
||||||
|
|
||||||
7. Revoke documentation file permissions (optional).
|
|
||||||
|
|
||||||
Some administrators suggest making the documentation files, especially
|
|
||||||
CHANGELOG.txt, non-readable so that the exact version of Drupal you are
|
|
||||||
running is slightly more difficult to determine. If you wish to implement
|
|
||||||
this optional security measure, from a Unix/Linux command line you can use
|
|
||||||
the following command:
|
|
||||||
|
|
||||||
chmod a-r CHANGELOG.txt
|
|
||||||
|
|
||||||
Note that the example only affects CHANGELOG.txt. To completely hide all
|
|
||||||
documentation files from public view, repeat this command for each of the
|
|
||||||
Drupal documentation files in the installation directory, substituting the
|
|
||||||
name of each file for CHANGELOG.txt in the example.
|
|
||||||
|
|
||||||
For more information on setting file permissions, see "Modifying Linux,
|
|
||||||
Unix, and Mac file permissions" (http://drupal.org/node/202483) or
|
|
||||||
"Modifying Windows file permissions" (http://drupal.org/node/202491) in the
|
|
||||||
Drupal.org online documentation.
|
|
||||||
|
|
||||||
8. Set up independent "cron" maintenance jobs.
|
|
||||||
|
|
||||||
Many Drupal modules have tasks that must be run periodically, including the
|
|
||||||
Search module (building and updating the index used for keyword searching),
|
|
||||||
the Aggregator module (retrieving feeds from other sites), and the System
|
|
||||||
module (performing routine maintenance and pruning of database tables). These
|
|
||||||
tasks are known as "cron maintenance tasks", named after the Unix/Linux
|
|
||||||
"cron" utility.
|
|
||||||
|
|
||||||
When you install Drupal, its built-in cron feature is enabled, which
|
|
||||||
automatically runs the cron tasks periodically, triggered by people visiting
|
|
||||||
pages of your site. You can configure the built-in cron feature by navigating
|
|
||||||
to Administration > Configuration > System > Cron.
|
|
||||||
|
|
||||||
It is also possible to run the cron tasks independent of site visits; this is
|
|
||||||
recommended for most sites. To do this, you will need to set up an automated
|
|
||||||
process to visit the page cron.php on your site, which executes the cron
|
|
||||||
tasks.
|
|
||||||
|
|
||||||
The URL of the cron.php page requires a "cron key" to protect against
|
|
||||||
unauthorized access. Your site's cron key is automatically generated during
|
|
||||||
installation and is specific to your site. The full URL of the page, with the
|
|
||||||
cron key, is available in the "Cron maintenance tasks" section of the Status
|
|
||||||
report page at Administration > Reports > Status report.
|
|
||||||
|
|
||||||
As an example for how to set up this automated process, you can use the
|
|
||||||
crontab utility on Unix/Linux systems. The following crontab line uses the
|
|
||||||
wget command to visit the cron.php page, and runs each hour, on the hour:
|
|
||||||
|
|
||||||
0 * * * * wget -O - -q -t 1 http://example.com/cron.php?cron_key=YOURKEY
|
|
||||||
|
|
||||||
Replace the text "http://example.com/cron.php?cron_key=YOURKEY" in the
|
|
||||||
example with the full URL displayed under "Cron maintenance tasks" on the
|
|
||||||
"Status report" page.
|
|
||||||
|
|
||||||
More information about cron maintenance tasks is available at
|
|
||||||
http://drupal.org/cron, and sample cron shell scripts can be found in the
|
|
||||||
scripts/ directory. (Note that these scripts must be customized like the
|
|
||||||
above example, to add your site-specific cron key and domain name.)
|
|
||||||
|
|
||||||
BUILDING AND CUSTOMIZING YOUR SITE
|
|
||||||
----------------------------------
|
|
||||||
|
|
||||||
A new installation of Drupal defaults to a very basic configuration. To extend
|
|
||||||
your site, you use "modules" and "themes". A module is a plugin that adds
|
|
||||||
functionality to Drupal, while a theme changes the look of your site. The core
|
|
||||||
of Drupal provides several optional modules and themes, and you can download
|
|
||||||
more at http://drupal.org/project/modules and http://drupal.org/project/themes
|
|
||||||
|
|
||||||
Do not mix downloaded or custom modules and themes with Drupal's core modules
|
|
||||||
and themes. Drupal's modules and themes are located in the top-level modules and
|
|
||||||
themes directories, while the modules and themes you add to Drupal are normally
|
|
||||||
placed in the sites/all/modules and sites/all/themes directories. If you run a
|
|
||||||
multisite installation, you can also place modules and themes in the
|
|
||||||
site-specific directories -- see the Multisite Configuration section, below.
|
|
||||||
|
|
||||||
Never edit Drupal's core modules and themes; instead, use the hooks available in
|
|
||||||
the Drupal API. To modify the behavior of Drupal, develop a module as described
|
|
||||||
at http://drupal.org/developing/modules. To modify the look of Drupal, create a
|
|
||||||
subtheme as described at http://drupal.org/node/225125, or a completely new
|
|
||||||
theme as described at http://drupal.org/documentation/theme
|
|
||||||
|
|
||||||
MULTISITE CONFIGURATION
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
A single Drupal installation can host several Drupal-powered sites, each with
|
|
||||||
its own individual configuration.
|
|
||||||
|
|
||||||
Additional site configurations are created in subdirectories within the 'sites'
|
|
||||||
directory. Each subdirectory must have a 'settings.php' file, which specifies
|
|
||||||
the configuration settings. The easiest way to create additional sites is to
|
|
||||||
copy the 'default' directory and modify the 'settings.php' file as appropriate.
|
|
||||||
The new directory name is constructed from the site's URL. The configuration for
|
|
||||||
www.example.com could be in 'sites/example.com/settings.php' (note that 'www.'
|
|
||||||
should be omitted if users can access your site at http://example.com/).
|
|
||||||
|
|
||||||
Sites do not have to have a different domain. You can also use subdomains and
|
|
||||||
subdirectories for Drupal sites. For example, example.com, sub.example.com, and
|
|
||||||
sub.example.com/site3 can all be defined as independent Drupal sites. The setup
|
|
||||||
for a configuration such as this would look like the following:
|
|
||||||
|
|
||||||
sites/default/settings.php
|
|
||||||
sites/example.com/settings.php
|
|
||||||
sites/sub.example.com/settings.php
|
|
||||||
sites/sub.example.com.site3/settings.php
|
|
||||||
|
|
||||||
When searching for a site configuration (for example www.sub.example.com/site3),
|
|
||||||
Drupal will search for configuration files in the following order, using the
|
|
||||||
first configuration it finds:
|
|
||||||
|
|
||||||
sites/www.sub.example.com.site3/settings.php
|
|
||||||
sites/sub.example.com.site3/settings.php
|
|
||||||
sites/example.com.site3/settings.php
|
|
||||||
sites/www.sub.example.com/settings.php
|
|
||||||
sites/sub.example.com/settings.php
|
|
||||||
sites/example.com/settings.php
|
|
||||||
sites/default/settings.php
|
|
||||||
|
|
||||||
If you are installing on a non-standard port, the port number is treated as the
|
|
||||||
deepest subdomain. For example: http://www.example.com:8080/ could be loaded
|
|
||||||
from sites/8080.www.example.com/. The port number will be removed according to
|
|
||||||
the pattern above if no port-specific configuration is found, just like a real
|
|
||||||
subdomain.
|
|
||||||
|
|
||||||
Each site configuration can have its own site-specific modules and themes in
|
|
||||||
addition to those installed in the standard 'modules' and 'themes' directories.
|
|
||||||
To use site-specific modules or themes, simply create a 'modules' or 'themes'
|
|
||||||
directory within the site configuration directory. For example, if
|
|
||||||
sub.example.com has a custom theme and a custom module that should not be
|
|
||||||
accessible to other sites, the setup would look like this:
|
|
||||||
|
|
||||||
sites/sub.example.com/
|
|
||||||
settings.php
|
|
||||||
themes/custom_theme
|
|
||||||
modules/custom_module
|
|
||||||
|
|
||||||
NOTE: for more information about multiple virtual hosts or the configuration
|
|
||||||
settings, consult http://drupal.org/getting-started/6/install/multi-site
|
|
||||||
|
|
||||||
For more information on configuring Drupal's file system path in a multisite
|
|
||||||
configuration, see step 6 above.
|
|
||||||
|
|
||||||
MORE INFORMATION
|
|
||||||
----------------
|
|
||||||
|
|
||||||
- See the Drupal.org online documentation:
|
|
||||||
http://drupal.org/documentation
|
|
||||||
|
|
||||||
- For a list of security announcements, see the "Security advisories" page at
|
|
||||||
http://drupal.org/security (available as an RSS feed). This page also
|
|
||||||
describes how to subscribe to these announcements via e-mail.
|
|
||||||
|
|
||||||
- For information about the Drupal security process, or to find out how to
|
|
||||||
report a potential security issue to the Drupal security team, see the
|
|
||||||
"Security team" page at http://drupal.org/security-team
|
|
||||||
|
|
||||||
- For information about the wide range of available support options, visit
|
|
||||||
http://drupal.org and click on Community and Support in the top or bottom
|
|
||||||
navigation.
|
|
||||||
@@ -71,12 +71,12 @@ profiles/your_site_profile/themes respectively to restrict their usage to only
|
|||||||
sites that were installed with that specific profile.
|
sites that were installed with that specific profile.
|
||||||
|
|
||||||
More about installation profiles and distributions:
|
More about installation profiles and distributions:
|
||||||
* Read about the difference between installation profiles and distributions:
|
* Read about the difference between installation profiles and distributions:
|
||||||
http://drupal.org/node/1089736
|
http://drupal.org/node/1089736
|
||||||
* Download contributed installation profiles and distributions:
|
* Download contributed installation profiles and distributions:
|
||||||
http://drupal.org/project/distributions
|
http://drupal.org/project/distributions
|
||||||
* Develop your own installation profile or distribution:
|
* Develop your own installation profile or distribution:
|
||||||
http://drupal.org/developing/distributions
|
http://drupal.org/developing/distributions
|
||||||
|
|
||||||
APPEARANCE
|
APPEARANCE
|
||||||
----------
|
----------
|
||||||
|
|||||||
@@ -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 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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() {
|
|||||||
* 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');
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
diff --git a/includes/entity.inc b/includes/entity.inc
|
||||||
|
index 2fefd59..0b80d53 100644
|
||||||
|
--- a/includes/entity.inc
|
||||||
|
+++ b/includes/entity.inc
|
||||||
|
@@ -159,6 +159,18 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
|
||||||
|
*/
|
||||||
|
public function load($ids = array(), $conditions = array()) {
|
||||||
|
$entities = array();
|
||||||
|
+
|
||||||
|
+ # PATCH http://drupal.org/node/1003788#comment-5195682
|
||||||
|
+ // Clean the $ids array to remove non-integer values that can be passed
|
||||||
|
+ // in from various sources, including menu callbacks.
|
||||||
|
+ if (is_array($ids)) {
|
||||||
|
+ foreach ($ids as $key => $id) {
|
||||||
|
+ if (empty($id) || ((string) $id !== (string) (int) $id)) {
|
||||||
|
+ unset($ids[$key]);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ # endpatch
|
||||||
|
|
||||||
|
// Revisions are not statically cached, and require a different query to
|
||||||
|
// other conditions, so separate the revision id into its own variable.
|
||||||
|
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 862 B |
@@ -251,8 +251,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]);
|
||||||
@@ -308,10 +308,11 @@ function ajax_render($commands = array()) {
|
|||||||
* 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() {
|
||||||
@@ -331,6 +332,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;
|
||||||
|
|
||||||
@@ -345,7 +357,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -366,7 +378,7 @@ function ajax_get_form() {
|
|||||||
* @see system_menu()
|
* @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
|
||||||
@@ -379,7 +391,19 @@ function ajax_form_callback() {
|
|||||||
$callback = $form_state['triggering_element']['#ajax']['callback'];
|
$callback = $form_state['triggering_element']['#ajax']['callback'];
|
||||||
}
|
}
|
||||||
if (!empty($callback) && function_exists($callback)) {
|
if (!empty($callback) && function_exists($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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -836,7 +860,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(
|
||||||
@@ -1209,3 +1234,26 @@ function ajax_command_restripe($selector) {
|
|||||||
'selector' => $selector,
|
'selector' => $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'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
/**
|
/**
|
||||||
* The current system version.
|
* The current system version.
|
||||||
*/
|
*/
|
||||||
define('VERSION', '7.19');
|
define('VERSION', '7.28');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Core API compatibility.
|
* Core API compatibility.
|
||||||
@@ -218,12 +218,16 @@ define('LANGUAGE_RTL', 1);
|
|||||||
define('REQUEST_TIME', (int) $_SERVER['REQUEST_TIME']);
|
define('REQUEST_TIME', (int) $_SERVER['REQUEST_TIME']);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag for drupal_set_title(); text is not sanitized, so run check_plain().
|
* Flag used to indicate that text is not sanitized, so run check_plain().
|
||||||
|
*
|
||||||
|
* @see drupal_set_title()
|
||||||
*/
|
*/
|
||||||
define('CHECK_PLAIN', 0);
|
define('CHECK_PLAIN', 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag for drupal_set_title(); text has already been sanitized.
|
* Flag used to indicate that text has already been sanitized.
|
||||||
|
*
|
||||||
|
* @see drupal_set_title()
|
||||||
*/
|
*/
|
||||||
define('PASS_THROUGH', -1);
|
define('PASS_THROUGH', -1);
|
||||||
|
|
||||||
@@ -240,7 +244,7 @@ define('REGISTRY_WRITE_LOOKUP_CACHE', 2);
|
|||||||
/**
|
/**
|
||||||
* Regular expression to match PHP function names.
|
* Regular expression to match PHP function names.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/language.functions.php
|
* @see http://php.net/manual/language.functions.php
|
||||||
*/
|
*/
|
||||||
define('DRUPAL_PHP_FUNCTION_PATTERN', '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*');
|
define('DRUPAL_PHP_FUNCTION_PATTERN', '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*');
|
||||||
|
|
||||||
@@ -274,7 +278,7 @@ define('DRUPAL_PHP_FUNCTION_PATTERN', '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
|
|||||||
* error, and $var will be populated with the contents of $object['foo'], but
|
* error, and $var will be populated with the contents of $object['foo'], but
|
||||||
* that data will be passed by value, not reference. For more information on
|
* that data will be passed by value, not reference. For more information on
|
||||||
* the PHP limitation, see the note in the official PHP documentation at·
|
* the PHP limitation, see the note in the official PHP documentation at·
|
||||||
* http://php.net/manual/en/arrayaccess.offsetget.php on
|
* http://php.net/manual/arrayaccess.offsetget.php on
|
||||||
* ArrayAccess::offsetGet().
|
* ArrayAccess::offsetGet().
|
||||||
*
|
*
|
||||||
* By default, the class accounts for caches where calling functions might
|
* By default, the class accounts for caches where calling functions might
|
||||||
@@ -380,11 +384,11 @@ abstract class DrupalCacheArray implements ArrayAccess {
|
|||||||
* without necessarily writing back to the persistent cache at the end.
|
* without necessarily writing back to the persistent cache at the end.
|
||||||
*
|
*
|
||||||
* @param $offset
|
* @param $offset
|
||||||
* The array offset that was request.
|
* The array offset that was requested.
|
||||||
* @param $persist
|
* @param $persist
|
||||||
* Optional boolean to specify whether the offset should be persisted or
|
* Optional boolean to specify whether the offset should be persisted or
|
||||||
* not, defaults to TRUE. When called with $persist = FALSE the offset will
|
* not, defaults to TRUE. When called with $persist = FALSE the offset will
|
||||||
* be unflagged so that it will not written at the end of the request.
|
* be unflagged so that it will not be written at the end of the request.
|
||||||
*/
|
*/
|
||||||
protected function persist($offset, $persist = TRUE) {
|
protected function persist($offset, $persist = TRUE) {
|
||||||
$this->keysToPersist[$offset] = $persist;
|
$this->keysToPersist[$offset] = $persist;
|
||||||
@@ -679,7 +683,8 @@ function drupal_environment_initialize() {
|
|||||||
ini_set('session.use_only_cookies', '1');
|
ini_set('session.use_only_cookies', '1');
|
||||||
ini_set('session.use_trans_sid', '0');
|
ini_set('session.use_trans_sid', '0');
|
||||||
// Don't send HTTP headers using PHP's session handler.
|
// Don't send HTTP headers using PHP's session handler.
|
||||||
ini_set('session.cache_limiter', 'none');
|
// An empty string is used here to disable the cache limiter.
|
||||||
|
ini_set('session.cache_limiter', '');
|
||||||
// Use httponly session cookies.
|
// Use httponly session cookies.
|
||||||
ini_set('session.cookie_httponly', '1');
|
ini_set('session.cookie_httponly', '1');
|
||||||
|
|
||||||
@@ -716,7 +721,6 @@ function drupal_settings_initialize() {
|
|||||||
if (isset($base_url)) {
|
if (isset($base_url)) {
|
||||||
// Parse fixed base URL from settings.php.
|
// Parse fixed base URL from settings.php.
|
||||||
$parts = parse_url($base_url);
|
$parts = parse_url($base_url);
|
||||||
$http_protocol = $parts['scheme'];
|
|
||||||
if (!isset($parts['path'])) {
|
if (!isset($parts['path'])) {
|
||||||
$parts['path'] = '';
|
$parts['path'] = '';
|
||||||
}
|
}
|
||||||
@@ -792,7 +796,7 @@ function drupal_settings_initialize() {
|
|||||||
*
|
*
|
||||||
* This function plays a key role in allowing Drupal's resources (modules
|
* This function plays a key role in allowing Drupal's resources (modules
|
||||||
* and themes) to be located in different places depending on a site's
|
* and themes) to be located in different places depending on a site's
|
||||||
* configuration. For example, a module 'foo' may legally be be located
|
* configuration. For example, a module 'foo' may legally be located
|
||||||
* in any of these three places:
|
* in any of these three places:
|
||||||
*
|
*
|
||||||
* modules/foo/foo.module
|
* modules/foo/foo.module
|
||||||
@@ -803,7 +807,7 @@ function drupal_settings_initialize() {
|
|||||||
* the above, depending on where the module is located.
|
* the above, depending on where the module is located.
|
||||||
*
|
*
|
||||||
* @param $type
|
* @param $type
|
||||||
* The type of the item (i.e. theme, theme_engine, module, profile).
|
* The type of the item (theme, theme_engine, module, profile).
|
||||||
* @param $name
|
* @param $name
|
||||||
* The name of the item for which the filename is requested.
|
* The name of the item for which the filename is requested.
|
||||||
* @param $filename
|
* @param $filename
|
||||||
@@ -811,7 +815,7 @@ function drupal_settings_initialize() {
|
|||||||
* than by consulting the database.
|
* than by consulting the database.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* The filename of the requested item.
|
* The filename of the requested item or NULL if the item is not found.
|
||||||
*/
|
*/
|
||||||
function drupal_get_filename($type, $name, $filename = NULL) {
|
function drupal_get_filename($type, $name, $filename = NULL) {
|
||||||
// The location of files will not change during the request, so do not use
|
// The location of files will not change during the request, so do not use
|
||||||
@@ -1186,10 +1190,11 @@ function _drupal_set_preferred_header_name($name = NULL) {
|
|||||||
* Headers are set in drupal_add_http_header(). Default headers are not set
|
* Headers are set in drupal_add_http_header(). Default headers are not set
|
||||||
* if they have been replaced or unset using drupal_add_http_header().
|
* if they have been replaced or unset using drupal_add_http_header().
|
||||||
*
|
*
|
||||||
* @param $default_headers
|
* @param array $default_headers
|
||||||
* An array of headers as name/value pairs.
|
* (optional) An array of headers as name/value pairs.
|
||||||
* @param $single
|
* @param bool $only_default
|
||||||
* If TRUE and headers have already be sent, send only the specified header.
|
* (optional) If TRUE and headers have already been sent, send only the
|
||||||
|
* specified headers.
|
||||||
*/
|
*/
|
||||||
function drupal_send_headers($default_headers = array(), $only_default = FALSE) {
|
function drupal_send_headers($default_headers = array(), $only_default = FALSE) {
|
||||||
$headers_sent = &drupal_static(__FUNCTION__, FALSE);
|
$headers_sent = &drupal_static(__FUNCTION__, FALSE);
|
||||||
@@ -1212,7 +1217,7 @@ function drupal_send_headers($default_headers = array(), $only_default = FALSE)
|
|||||||
header($_SERVER['SERVER_PROTOCOL'] . ' ' . $value);
|
header($_SERVER['SERVER_PROTOCOL'] . ' ' . $value);
|
||||||
}
|
}
|
||||||
// Skip headers that have been unset.
|
// Skip headers that have been unset.
|
||||||
elseif ($value) {
|
elseif ($value !== FALSE) {
|
||||||
header($header_names[$name_lower] . ': ' . $value);
|
header($header_names[$name_lower] . ': ' . $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1274,7 +1279,7 @@ function drupal_page_header() {
|
|||||||
*/
|
*/
|
||||||
function drupal_serve_page_from_cache(stdClass $cache) {
|
function drupal_serve_page_from_cache(stdClass $cache) {
|
||||||
// Negotiate whether to use compression.
|
// Negotiate whether to use compression.
|
||||||
$page_compression = variable_get('page_compression', TRUE) && extension_loaded('zlib');
|
$page_compression = !empty($cache->data['page_compressed']);
|
||||||
$return_compressed = $page_compression && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE;
|
$return_compressed = $page_compression && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE;
|
||||||
|
|
||||||
// Get headers set in hook_boot(). Keys are lower-case.
|
// Get headers set in hook_boot(). Keys are lower-case.
|
||||||
@@ -1405,6 +1410,7 @@ function drupal_unpack($obj, $field = 'data') {
|
|||||||
* more information, including recommendations on how to break up or not
|
* more information, including recommendations on how to break up or not
|
||||||
* break up strings for translation.
|
* break up strings for translation.
|
||||||
*
|
*
|
||||||
|
* @section sec_translating_vars Translating Variables
|
||||||
* You should never use t() to translate variables, such as calling
|
* You should never use t() to translate variables, such as calling
|
||||||
* @code t($text); @endcode, unless the text that the variable holds has been
|
* @code t($text); @endcode, unless the text that the variable holds has been
|
||||||
* passed through t() elsewhere (e.g., $text is one of several translated
|
* passed through t() elsewhere (e.g., $text is one of several translated
|
||||||
@@ -1420,9 +1426,11 @@ function drupal_unpack($obj, $field = 'data') {
|
|||||||
* Basically, you can put variables like @name into your string, and t() will
|
* Basically, you can put variables like @name into your string, and t() will
|
||||||
* substitute their sanitized values at translation time. (See the
|
* substitute their sanitized values at translation time. (See the
|
||||||
* Localization API pages referenced above and the documentation of
|
* Localization API pages referenced above and the documentation of
|
||||||
* format_string() for details.) Translators can then rearrange the string as
|
* format_string() for details about how to define variables in your string.)
|
||||||
* necessary for the language (e.g., in Spanish, it might be "blog de @name").
|
* Translators can then rearrange the string as necessary for the language
|
||||||
|
* (e.g., in Spanish, it might be "blog de @name").
|
||||||
*
|
*
|
||||||
|
* @section sec_alt_funcs_install Use During Installation Phase
|
||||||
* During the Drupal installation phase, some resources used by t() wil not be
|
* During the Drupal installation phase, some resources used by t() wil not be
|
||||||
* available to code that needs localization. See st() and get_t() for
|
* available to code that needs localization. See st() and get_t() for
|
||||||
* alternatives.
|
* alternatives.
|
||||||
@@ -1484,21 +1492,34 @@ function t($string, array $args = array(), array $options = array()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces placeholders with sanitized values in a string.
|
* Formats a string for HTML display by replacing variable placeholders.
|
||||||
|
*
|
||||||
|
* This function replaces variable placeholders in a string with the requested
|
||||||
|
* values and escapes the values so they can be safely displayed as HTML. It
|
||||||
|
* should be used on any unknown text that is intended to be printed to an HTML
|
||||||
|
* page (especially text that may have come from untrusted users, since in that
|
||||||
|
* case it prevents cross-site scripting and other security problems).
|
||||||
|
*
|
||||||
|
* In most cases, you should use t() rather than calling this function
|
||||||
|
* directly, since it will translate the text (on non-English-only sites) in
|
||||||
|
* addition to formatting it.
|
||||||
*
|
*
|
||||||
* @param $string
|
* @param $string
|
||||||
* A string containing placeholders.
|
* A string containing placeholders.
|
||||||
* @param $args
|
* @param $args
|
||||||
* An associative array of replacements to make. Occurrences in $string of
|
* An associative array of replacements to make. Occurrences in $string of
|
||||||
* any key in $args are replaced with the corresponding value, after
|
* any key in $args are replaced with the corresponding value, after optional
|
||||||
* sanitization. The sanitization function depends on the first character of
|
* sanitization and formatting. The type of sanitization and formatting
|
||||||
* the key:
|
* depends on the first character of the key:
|
||||||
* - !variable: Inserted as is. Use this for text that has already been
|
* - @variable: Escaped to HTML using check_plain(). Use this as the default
|
||||||
* sanitized.
|
* choice for anything displayed on a page on the site.
|
||||||
* - @variable: Escaped to HTML using check_plain(). Use this for anything
|
* - %variable: Escaped to HTML and formatted using drupal_placeholder(),
|
||||||
* displayed on a page on the site.
|
* which makes it display as <em>emphasized</em> text.
|
||||||
* - %variable: Escaped as a placeholder for user-submitted content using
|
* - !variable: Inserted as is, with no sanitization or formatting. Only use
|
||||||
* drupal_placeholder(), which shows up as <em>emphasized</em> text.
|
* this for text that has already been prepared for HTML display (for
|
||||||
|
* example, user-supplied text that has already been run through
|
||||||
|
* check_plain() previously, or is expected to contain some limited HTML
|
||||||
|
* tags and has already been run through filter_xss() previously).
|
||||||
*
|
*
|
||||||
* @see t()
|
* @see t()
|
||||||
* @ingroup sanitization
|
* @ingroup sanitization
|
||||||
@@ -1912,6 +1933,33 @@ function drupal_block_denied($ip) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a URL-safe, base64 encoded string of highly randomized bytes (over the full 8-bit range).
|
||||||
|
*
|
||||||
|
* @param $byte_count
|
||||||
|
* The number of random bytes to fetch and base64 encode.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The base64 encoded result will have a length of up to 4 * $byte_count.
|
||||||
|
*/
|
||||||
|
function drupal_random_key($byte_count = 32) {
|
||||||
|
return drupal_base64_encode(drupal_random_bytes($byte_count));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a URL-safe, base64 encoded version of the supplied string.
|
||||||
|
*
|
||||||
|
* @param $string
|
||||||
|
* The string to convert to base64.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function drupal_base64_encode($string) {
|
||||||
|
$data = base64_encode($string);
|
||||||
|
// Modify the output so it's safe to use in URLs.
|
||||||
|
return strtr($data, array('+' => '-', '/' => '_', '=' => ''));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a string of highly randomized bytes (over the full 8-bit range).
|
* Returns a string of highly randomized bytes (over the full 8-bit range).
|
||||||
*
|
*
|
||||||
@@ -1925,38 +1973,34 @@ function drupal_block_denied($ip) {
|
|||||||
*/
|
*/
|
||||||
function drupal_random_bytes($count) {
|
function drupal_random_bytes($count) {
|
||||||
// $random_state does not use drupal_static as it stores random bytes.
|
// $random_state does not use drupal_static as it stores random bytes.
|
||||||
static $random_state, $bytes, $php_compatible;
|
static $random_state, $bytes, $has_openssl;
|
||||||
// Initialize on the first call. The contents of $_SERVER includes a mix of
|
|
||||||
// user-specific and system information that varies a little with each page.
|
$missing_bytes = $count - strlen($bytes);
|
||||||
if (!isset($random_state)) {
|
|
||||||
$random_state = print_r($_SERVER, TRUE);
|
if ($missing_bytes > 0) {
|
||||||
if (function_exists('getmypid')) {
|
|
||||||
// Further initialize with the somewhat random PHP process ID.
|
|
||||||
$random_state .= getmypid();
|
|
||||||
}
|
|
||||||
$bytes = '';
|
|
||||||
}
|
|
||||||
if (strlen($bytes) < $count) {
|
|
||||||
// PHP versions prior 5.3.4 experienced openssl_random_pseudo_bytes()
|
// PHP versions prior 5.3.4 experienced openssl_random_pseudo_bytes()
|
||||||
// locking on Windows and rendered it unusable.
|
// locking on Windows and rendered it unusable.
|
||||||
if (!isset($php_compatible)) {
|
if (!isset($has_openssl)) {
|
||||||
$php_compatible = version_compare(PHP_VERSION, '5.3.4', '>=');
|
$has_openssl = version_compare(PHP_VERSION, '5.3.4', '>=') && function_exists('openssl_random_pseudo_bytes');
|
||||||
}
|
}
|
||||||
// /dev/urandom is available on many *nix systems and is considered the
|
|
||||||
// best commonly available pseudo-random source.
|
// openssl_random_pseudo_bytes() will find entropy in a system-dependent
|
||||||
if ($fh = @fopen('/dev/urandom', 'rb')) {
|
// way.
|
||||||
|
if ($has_openssl) {
|
||||||
|
$bytes .= openssl_random_pseudo_bytes($missing_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Else, read directly from /dev/urandom, which is available on many *nix
|
||||||
|
// systems and is considered cryptographically secure.
|
||||||
|
elseif ($fh = @fopen('/dev/urandom', 'rb')) {
|
||||||
// PHP only performs buffered reads, so in reality it will always read
|
// PHP only performs buffered reads, so in reality it will always read
|
||||||
// at least 4096 bytes. Thus, it costs nothing extra to read and store
|
// at least 4096 bytes. Thus, it costs nothing extra to read and store
|
||||||
// that much so as to speed any additional invocations.
|
// that much so as to speed any additional invocations.
|
||||||
$bytes .= fread($fh, max(4096, $count));
|
$bytes .= fread($fh, max(4096, $missing_bytes));
|
||||||
fclose($fh);
|
fclose($fh);
|
||||||
}
|
}
|
||||||
// openssl_random_pseudo_bytes() will find entropy in a system-dependent
|
|
||||||
// way.
|
// If we couldn't get enough entropy, this simple hash-based PRNG will
|
||||||
elseif ($php_compatible && function_exists('openssl_random_pseudo_bytes')) {
|
|
||||||
$bytes .= openssl_random_pseudo_bytes($count - strlen($bytes));
|
|
||||||
}
|
|
||||||
// If /dev/urandom is not available or returns no bytes, this loop will
|
|
||||||
// generate a good set of pseudo-random bytes on any system.
|
// generate a good set of pseudo-random bytes on any system.
|
||||||
// Note that it may be important that our $random_state is passed
|
// Note that it may be important that our $random_state is passed
|
||||||
// through hash() prior to being rolled into $output, that the two hash()
|
// through hash() prior to being rolled into $output, that the two hash()
|
||||||
@@ -1964,9 +2008,23 @@ function drupal_random_bytes($count) {
|
|||||||
// the microtime() - is prepended rather than appended. This is to avoid
|
// the microtime() - is prepended rather than appended. This is to avoid
|
||||||
// directly leaking $random_state via the $output stream, which could
|
// directly leaking $random_state via the $output stream, which could
|
||||||
// allow for trivial prediction of further "random" numbers.
|
// allow for trivial prediction of further "random" numbers.
|
||||||
while (strlen($bytes) < $count) {
|
if (strlen($bytes) < $count) {
|
||||||
$random_state = hash('sha256', microtime() . mt_rand() . $random_state);
|
// Initialize on the first call. The contents of $_SERVER includes a mix of
|
||||||
$bytes .= hash('sha256', mt_rand() . $random_state, TRUE);
|
// user-specific and system information that varies a little with each page.
|
||||||
|
if (!isset($random_state)) {
|
||||||
|
$random_state = print_r($_SERVER, TRUE);
|
||||||
|
if (function_exists('getmypid')) {
|
||||||
|
// Further initialize with the somewhat random PHP process ID.
|
||||||
|
$random_state .= getmypid();
|
||||||
|
}
|
||||||
|
$bytes = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
$random_state = hash('sha256', microtime() . mt_rand() . $random_state);
|
||||||
|
$bytes .= hash('sha256', mt_rand() . $random_state, TRUE);
|
||||||
|
}
|
||||||
|
while (strlen($bytes) < $count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$output = substr($bytes, 0, $count);
|
$output = substr($bytes, 0, $count);
|
||||||
@@ -1977,17 +2035,21 @@ function drupal_random_bytes($count) {
|
|||||||
/**
|
/**
|
||||||
* Calculates a base-64 encoded, URL-safe sha-256 hmac.
|
* Calculates a base-64 encoded, URL-safe sha-256 hmac.
|
||||||
*
|
*
|
||||||
* @param $data
|
* @param string $data
|
||||||
* String to be validated with the hmac.
|
* String to be validated with the hmac.
|
||||||
* @param $key
|
* @param string $key
|
||||||
* A secret string key.
|
* A secret string key.
|
||||||
*
|
*
|
||||||
* @return
|
* @return string
|
||||||
* A base-64 encoded sha-256 hmac, with + replaced with -, / with _ and
|
* A base-64 encoded sha-256 hmac, with + replaced with -, / with _ and
|
||||||
* any = padding characters removed.
|
* any = padding characters removed.
|
||||||
*/
|
*/
|
||||||
function drupal_hmac_base64($data, $key) {
|
function drupal_hmac_base64($data, $key) {
|
||||||
$hmac = base64_encode(hash_hmac('sha256', $data, $key, TRUE));
|
// Casting $data and $key to strings here is necessary to avoid empty string
|
||||||
|
// results of the hash function if they are not scalar values. As this
|
||||||
|
// function is used in security-critical contexts like token validation it is
|
||||||
|
// important that it never returns an empty string.
|
||||||
|
$hmac = base64_encode(hash_hmac('sha256', (string) $data, (string) $key, TRUE));
|
||||||
// Modify the hmac so it's safe to use in URLs.
|
// Modify the hmac so it's safe to use in URLs.
|
||||||
return strtr($hmac, array('+' => '-', '/' => '_', '=' => ''));
|
return strtr($hmac, array('+' => '-', '/' => '_', '=' => ''));
|
||||||
}
|
}
|
||||||
@@ -2088,7 +2150,7 @@ function drupal_array_merge_deep_array($arrays) {
|
|||||||
* @return Object - the user object.
|
* @return Object - the user object.
|
||||||
*/
|
*/
|
||||||
function drupal_anonymous_user() {
|
function drupal_anonymous_user() {
|
||||||
$user = new stdClass();
|
$user = variable_get('drupal_anonymous_user_object', new stdClass);
|
||||||
$user->uid = 0;
|
$user->uid = 0;
|
||||||
$user->hostname = ip_address();
|
$user->hostname = ip_address();
|
||||||
$user->roles = array();
|
$user->roles = array();
|
||||||
@@ -2218,6 +2280,19 @@ function drupal_get_user_timezone() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a salt useful for hardening against SQL injection.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* A salt based on information in settings.php, not in the database.
|
||||||
|
*/
|
||||||
|
function drupal_get_hash_salt() {
|
||||||
|
global $drupal_hash_salt, $databases;
|
||||||
|
// If the $drupal_hash_salt variable is empty, a hash of the serialized
|
||||||
|
// database credentials is used as a fallback salt.
|
||||||
|
return empty($drupal_hash_salt) ? hash('sha256', serialize($databases)) : $drupal_hash_salt;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides custom PHP error handling.
|
* Provides custom PHP error handling.
|
||||||
*
|
*
|
||||||
@@ -2438,7 +2513,6 @@ function drupal_get_bootstrap_phase() {
|
|||||||
* HMAC and timestamp.
|
* HMAC and timestamp.
|
||||||
*/
|
*/
|
||||||
function drupal_valid_test_ua() {
|
function drupal_valid_test_ua() {
|
||||||
global $drupal_hash_salt;
|
|
||||||
// No reason to reset this.
|
// No reason to reset this.
|
||||||
static $test_prefix;
|
static $test_prefix;
|
||||||
|
|
||||||
@@ -2452,7 +2526,7 @@ function drupal_valid_test_ua() {
|
|||||||
// We use the salt from settings.php to make the HMAC key, since
|
// We use the salt from settings.php to make the HMAC key, since
|
||||||
// the database is not yet initialized and we can't access any Drupal variables.
|
// the database is not yet initialized and we can't access any Drupal variables.
|
||||||
// The file properties add more entropy not easily accessible to others.
|
// The file properties add more entropy not easily accessible to others.
|
||||||
$key = $drupal_hash_salt . filectime(__FILE__) . fileinode(__FILE__);
|
$key = drupal_get_hash_salt() . filectime(__FILE__) . fileinode(__FILE__);
|
||||||
$time_diff = REQUEST_TIME - $time;
|
$time_diff = REQUEST_TIME - $time;
|
||||||
// Since we are making a local request a 5 second time window is allowed,
|
// Since we are making a local request a 5 second time window is allowed,
|
||||||
// and the HMAC must match.
|
// and the HMAC must match.
|
||||||
@@ -2470,14 +2544,13 @@ function drupal_valid_test_ua() {
|
|||||||
* Generates a user agent string with a HMAC and timestamp for simpletest.
|
* Generates a user agent string with a HMAC and timestamp for simpletest.
|
||||||
*/
|
*/
|
||||||
function drupal_generate_test_ua($prefix) {
|
function drupal_generate_test_ua($prefix) {
|
||||||
global $drupal_hash_salt;
|
|
||||||
static $key;
|
static $key;
|
||||||
|
|
||||||
if (!isset($key)) {
|
if (!isset($key)) {
|
||||||
// We use the salt from settings.php to make the HMAC key, since
|
// We use the salt from settings.php to make the HMAC key, since
|
||||||
// the database is not yet initialized and we can't access any Drupal variables.
|
// the database is not yet initialized and we can't access any Drupal variables.
|
||||||
// The file properties add more entropy not easily accessible to others.
|
// The file properties add more entropy not easily accessible to others.
|
||||||
$key = $drupal_hash_salt . filectime(__FILE__) . fileinode(__FILE__);
|
$key = drupal_get_hash_salt() . filectime(__FILE__) . fileinode(__FILE__);
|
||||||
}
|
}
|
||||||
// Generate a moderately secure HMAC based on the database credentials.
|
// Generate a moderately secure HMAC based on the database credentials.
|
||||||
$salt = uniqid('', TRUE);
|
$salt = uniqid('', TRUE);
|
||||||
@@ -3222,8 +3295,8 @@ function registry_update() {
|
|||||||
* However, the above line of code does not work, because PHP only allows static
|
* However, the above line of code does not work, because PHP only allows static
|
||||||
* variables to be initializied by literal values, and does not allow static
|
* variables to be initializied by literal values, and does not allow static
|
||||||
* variables to be assigned to references.
|
* variables to be assigned to references.
|
||||||
* - http://php.net/manual/en/language.variables.scope.php#language.variables.scope.static
|
* - http://php.net/manual/language.variables.scope.php#language.variables.scope.static
|
||||||
* - http://php.net/manual/en/language.variables.scope.php#language.variables.scope.references
|
* - http://php.net/manual/language.variables.scope.php#language.variables.scope.references
|
||||||
* The example below shows the syntax needed to work around both limitations.
|
* The example below shows the syntax needed to work around both limitations.
|
||||||
* For benchmarks and more information, see http://drupal.org/node/619666.
|
* For benchmarks and more information, see http://drupal.org/node/619666.
|
||||||
*
|
*
|
||||||
@@ -3383,3 +3456,32 @@ function _drupal_shutdown_function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares the memory required for an operation to the available memory.
|
||||||
|
*
|
||||||
|
* @param $required
|
||||||
|
* The memory required for the operation, expressed as a number of bytes with
|
||||||
|
* optional SI or IEC binary unit prefix (e.g. 2, 3K, 5MB, 10G, 6GiB, 8bytes,
|
||||||
|
* 9mbytes).
|
||||||
|
* @param $memory_limit
|
||||||
|
* (optional) The memory limit for the operation, expressed as a number of
|
||||||
|
* bytes with optional SI or IEC binary unit prefix (e.g. 2, 3K, 5MB, 10G,
|
||||||
|
* 6GiB, 8bytes, 9mbytes). If no value is passed, the current PHP
|
||||||
|
* memory_limit will be used. Defaults to NULL.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* TRUE if there is sufficient memory to allow the operation, or FALSE
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
function drupal_check_memory_limit($required, $memory_limit = NULL) {
|
||||||
|
if (!isset($memory_limit)) {
|
||||||
|
$memory_limit = ini_get('memory_limit');
|
||||||
|
}
|
||||||
|
|
||||||
|
// There is sufficient memory if:
|
||||||
|
// - No memory limit is set.
|
||||||
|
// - The memory limit is set to unlimited (-1).
|
||||||
|
// - The memory limit is greater than the memory required for the operation.
|
||||||
|
return ((!$memory_limit) || ($memory_limit == -1) || (parse_size($memory_limit) >= parse_size($required)));
|
||||||
|
}
|
||||||
|
|||||||
@@ -80,43 +80,15 @@ function cache_get_multiple(array &$cids, $bin = 'cache') {
|
|||||||
* same name. Other implementations might want to store several bins in data
|
* same name. Other implementations might want to store several bins in data
|
||||||
* structures that get flushed together. While it is not a problem for most
|
* structures that get flushed together. While it is not a problem for most
|
||||||
* cache bins if the entries in them are flushed before their expire time, some
|
* cache bins if the entries in them are flushed before their expire time, some
|
||||||
* might break functionality or are extremely expensive to recalculate. These
|
* might break functionality or are extremely expensive to recalculate. The
|
||||||
* will be marked with a (*). The other bins expired automatically by core.
|
* other bins are expired automatically by core. Contributed modules can add
|
||||||
* Contributed modules can add additional bins and get them expired
|
* additional bins and get them expired automatically by implementing
|
||||||
* automatically by implementing hook_flush_caches().
|
* hook_flush_caches().
|
||||||
*
|
|
||||||
* - cache: Generic cache storage bin (used for variables, theme registry,
|
|
||||||
* locale date, list of simpletest tests etc).
|
|
||||||
*
|
|
||||||
* - cache_block: Stores the content of various blocks.
|
|
||||||
*
|
|
||||||
* - cache field: Stores the field data belonging to a given object.
|
|
||||||
*
|
|
||||||
* - cache_filter: Stores filtered pieces of content.
|
|
||||||
*
|
|
||||||
* - cache_form(*): Stores multistep forms. Flushing this bin means that some
|
|
||||||
* forms displayed to users lose their state and the data already submitted
|
|
||||||
* to them.
|
|
||||||
*
|
|
||||||
* - cache_menu: Stores the structure of visible navigation menus per page.
|
|
||||||
*
|
|
||||||
* - cache_page: Stores generated pages for anonymous users. It is flushed
|
|
||||||
* very often, whenever a page changes, at least for every ode and comment
|
|
||||||
* submission. This is the only bin affected by the page cache setting on
|
|
||||||
* the administrator panel.
|
|
||||||
*
|
|
||||||
* - cache path: Stores the system paths that have an alias.
|
|
||||||
*
|
|
||||||
* - cache update(*): Stores available releases. The update server (for
|
|
||||||
* example, drupal.org) needs to produce the relevant XML for every project
|
|
||||||
* installed on the current site. As this is different for (almost) every
|
|
||||||
* site, it's very expensive to recalculate for the update server.
|
|
||||||
*
|
*
|
||||||
* The reasons for having several bins are as follows:
|
* The reasons for having several bins are as follows:
|
||||||
*
|
* - Smaller bins mean smaller database tables and allow for faster selects and
|
||||||
* - smaller bins mean smaller database tables and allow for faster selects and
|
* inserts.
|
||||||
* inserts
|
* - We try to put fast changing cache items and rather static ones into
|
||||||
* - we try to put fast changing cache items and rather static ones into
|
|
||||||
* different bins. The effect is that only the fast changing bins will need a
|
* different bins. The effect is that only the fast changing bins will need a
|
||||||
* lot of writes to disk. The more static bins will also be better cacheable
|
* lot of writes to disk. The more static bins will also be better cacheable
|
||||||
* with MySQL's query cache.
|
* with MySQL's query cache.
|
||||||
@@ -125,13 +97,27 @@ function cache_get_multiple(array &$cids, $bin = 'cache') {
|
|||||||
* The cache ID of the data to store.
|
* The cache ID of the data to store.
|
||||||
* @param $data
|
* @param $data
|
||||||
* The data to store in the cache. Complex data types will be automatically
|
* The data to store in the cache. Complex data types will be automatically
|
||||||
* serialized before insertion.
|
* serialized before insertion. Strings will be stored as plain text and are
|
||||||
* Strings will be stored as plain text and not serialized.
|
* not serialized.
|
||||||
* @param $bin
|
* @param $bin
|
||||||
* The cache bin to store the data in. Valid core values are 'cache_block',
|
* The cache bin to store the data in. Valid core values are:
|
||||||
* 'cache_bootstrap', 'cache_field', 'cache_filter', 'cache_form',
|
* - cache: (default) Generic cache storage bin (used for theme registry,
|
||||||
* 'cache_menu', 'cache_page', 'cache_update' or 'cache' for the default
|
* locale date, list of simpletest tests, etc.).
|
||||||
* cache.
|
* - cache_block: Stores the content of various blocks.
|
||||||
|
* - cache_bootstrap: Stores the class registry, the system list of modules,
|
||||||
|
* the list of which modules implement which hooks, and the Drupal variable
|
||||||
|
* list.
|
||||||
|
* - cache_field: Stores the field data belonging to a given object.
|
||||||
|
* - cache_filter: Stores filtered pieces of content.
|
||||||
|
* - cache_form: Stores multistep forms. Flushing this bin means that some
|
||||||
|
* forms displayed to users lose their state and the data already submitted
|
||||||
|
* to them. This bin should not be flushed before its expired time.
|
||||||
|
* - cache_menu: Stores the structure of visible navigation menus per page.
|
||||||
|
* - cache_page: Stores generated pages for anonymous users. It is flushed
|
||||||
|
* very often, whenever a page changes, at least for every node and comment
|
||||||
|
* submission. This is the only bin affected by the page cache setting on
|
||||||
|
* the administrator panel.
|
||||||
|
* - cache_path: Stores the system paths that have an alias.
|
||||||
* @param $expire
|
* @param $expire
|
||||||
* One of the following values:
|
* One of the following values:
|
||||||
* - CACHE_PERMANENT: Indicates that the item should never be removed unless
|
* - CACHE_PERMANENT: Indicates that the item should never be removed unless
|
||||||
@@ -141,6 +127,7 @@ function cache_get_multiple(array &$cids, $bin = 'cache') {
|
|||||||
* - A Unix timestamp: Indicates that the item should be kept at least until
|
* - A Unix timestamp: Indicates that the item should be kept at least until
|
||||||
* the given time, after which it behaves like CACHE_TEMPORARY.
|
* the given time, after which it behaves like CACHE_TEMPORARY.
|
||||||
*
|
*
|
||||||
|
* @see _update_cache_set()
|
||||||
* @see cache_get()
|
* @see cache_get()
|
||||||
*/
|
*/
|
||||||
function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) {
|
function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) {
|
||||||
@@ -150,18 +137,20 @@ function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) {
|
|||||||
/**
|
/**
|
||||||
* Expires data from the cache.
|
* Expires data from the cache.
|
||||||
*
|
*
|
||||||
* If called without arguments, expirable entries will be cleared from the
|
* If called with the arguments $cid and $bin set to NULL or omitted, then
|
||||||
* cache_page and cache_block bins.
|
* expirable entries will be cleared from the cache_page and cache_block bins,
|
||||||
|
* and the $wildcard argument is ignored.
|
||||||
*
|
*
|
||||||
* @param $cid
|
* @param $cid
|
||||||
* If set, the cache ID to delete. Otherwise, all cache entries that can
|
* If set, the cache ID or an array of cache IDs. Otherwise, all cache entries
|
||||||
* expire are deleted.
|
* that can expire are deleted. The $wildcard argument will be ignored if set
|
||||||
|
* to NULL.
|
||||||
* @param $bin
|
* @param $bin
|
||||||
* If set, the cache bin to delete from. Mandatory argument if $cid is set.
|
* If set, the cache bin to delete from. Mandatory argument if $cid is set.
|
||||||
* @param $wildcard
|
* @param $wildcard
|
||||||
* If TRUE, cache IDs starting with $cid are deleted in addition to the
|
* If TRUE, the $cid argument must contain a string value and cache IDs
|
||||||
* exact cache ID specified by $cid. If $wildcard is TRUE and $cid is '*',
|
* starting with $cid are deleted in addition to the exact cache ID specified
|
||||||
* the entire cache bin is emptied.
|
* by $cid. If $wildcard is TRUE and $cid is '*', the entire cache is emptied.
|
||||||
*/
|
*/
|
||||||
function cache_clear_all($cid = NULL, $bin = NULL, $wildcard = FALSE) {
|
function cache_clear_all($cid = NULL, $bin = NULL, $wildcard = FALSE) {
|
||||||
if (!isset($cid) && !isset($bin)) {
|
if (!isset($cid) && !isset($bin)) {
|
||||||
@@ -230,13 +219,6 @@ function cache_is_empty($bin) {
|
|||||||
* @see DrupalDatabaseCache
|
* @see DrupalDatabaseCache
|
||||||
*/
|
*/
|
||||||
interface DrupalCacheInterface {
|
interface DrupalCacheInterface {
|
||||||
/**
|
|
||||||
* Constructs a new cache interface.
|
|
||||||
*
|
|
||||||
* @param $bin
|
|
||||||
* The cache bin for which the object is created.
|
|
||||||
*/
|
|
||||||
function __construct($bin);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns data from the persistent cache.
|
* Returns data from the persistent cache.
|
||||||
@@ -293,12 +275,14 @@ interface DrupalCacheInterface {
|
|||||||
* cache_page and cache_block bins.
|
* cache_page and cache_block bins.
|
||||||
*
|
*
|
||||||
* @param $cid
|
* @param $cid
|
||||||
* If set, the cache ID to delete. Otherwise, all cache entries that can
|
* If set, the cache ID or an array of cache IDs. Otherwise, all cache
|
||||||
* expire are deleted.
|
* entries that can expire are deleted. The $wildcard argument will be
|
||||||
|
* ignored if set to NULL.
|
||||||
* @param $wildcard
|
* @param $wildcard
|
||||||
* If set to TRUE, the $cid is treated as a substring
|
* If TRUE, the $cid argument must contain a string value and cache IDs
|
||||||
* to match rather than a complete ID. The match is a right hand
|
* starting with $cid are deleted in addition to the exact cache ID
|
||||||
* match. If '*' is given as $cid, the bin $bin will be emptied.
|
* specified by $cid. If $wildcard is TRUE and $cid is '*', the entire
|
||||||
|
* cache is emptied.
|
||||||
*/
|
*/
|
||||||
function clear($cid = NULL, $wildcard = FALSE);
|
function clear($cid = NULL, $wildcard = FALSE);
|
||||||
|
|
||||||
@@ -324,7 +308,10 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
|
|||||||
protected $bin;
|
protected $bin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new DrupalDatabaseCache object.
|
* Constructs a DrupalDatabaseCache object.
|
||||||
|
*
|
||||||
|
* @param $bin
|
||||||
|
* The cache bin for which the object is created.
|
||||||
*/
|
*/
|
||||||
function __construct($bin) {
|
function __construct($bin) {
|
||||||
$this->bin = $bin;
|
$this->bin = $bin;
|
||||||
@@ -518,7 +505,16 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
|
|||||||
else {
|
else {
|
||||||
if ($wildcard) {
|
if ($wildcard) {
|
||||||
if ($cid == '*') {
|
if ($cid == '*') {
|
||||||
db_truncate($this->bin)->execute();
|
// Check if $this->bin is a cache table before truncating. Other
|
||||||
|
// cache_clear_all() operations throw a PDO error in this situation,
|
||||||
|
// so we don't need to verify them first. This ensures that non-cache
|
||||||
|
// tables cannot be truncated accidentally.
|
||||||
|
if ($this->isValidBin()) {
|
||||||
|
db_truncate($this->bin)->execute();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new Exception(t('Invalid or missing cache bin specified: %bin', array('%bin' => $this->bin)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
db_delete($this->bin)
|
db_delete($this->bin)
|
||||||
@@ -555,4 +551,25 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
|
|||||||
->fetchField();
|
->fetchField();
|
||||||
return empty($result);
|
return empty($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if $this->bin represents a valid cache table.
|
||||||
|
*
|
||||||
|
* This check is required to ensure that non-cache tables are not truncated
|
||||||
|
* accidentally when calling cache_clear_all().
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
function isValidBin() {
|
||||||
|
if ($this->bin == 'cache' || substr($this->bin, 0, 6) == 'cache_') {
|
||||||
|
// Skip schema check for bins with standard table names.
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
// These fields are required for any cache table.
|
||||||
|
$fields = array('cid', 'data', 'expire', 'created', 'serialized');
|
||||||
|
// Load the table schema.
|
||||||
|
$schema = drupal_get_schema($this->bin);
|
||||||
|
// Confirm that all fields are present.
|
||||||
|
return isset($schema['fields']) && !array_diff($fields, array_keys($schema['fields']));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ function drupal_get_rdf_namespaces() {
|
|||||||
/**
|
/**
|
||||||
* Adds output to the HEAD tag of the HTML page.
|
* Adds output to the HEAD tag of the HTML page.
|
||||||
*
|
*
|
||||||
* This function can be called as long the headers aren't sent. Pass no
|
* This function can be called as long as the headers aren't sent. Pass no
|
||||||
* arguments (or NULL for both) to retrieve the currently stored elements.
|
* arguments (or NULL for both) to retrieve the currently stored elements.
|
||||||
*
|
*
|
||||||
* @param $data
|
* @param $data
|
||||||
@@ -458,7 +458,7 @@ function drupal_get_query_array($query) {
|
|||||||
$result = array();
|
$result = array();
|
||||||
if (!empty($query)) {
|
if (!empty($query)) {
|
||||||
foreach (explode('&', $query) as $param) {
|
foreach (explode('&', $query) as $param) {
|
||||||
$param = explode('=', $param);
|
$param = explode('=', $param, 2);
|
||||||
$result[$param[0]] = isset($param[1]) ? rawurldecode($param[1]) : '';
|
$result[$param[0]] = isset($param[1]) ? rawurldecode($param[1]) : '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -641,7 +641,7 @@ function drupal_encode_path($path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the user to a different Drupal page.
|
* Sends the user to a different page.
|
||||||
*
|
*
|
||||||
* This issues an on-site HTTP redirect. The function makes sure the redirected
|
* This issues an on-site HTTP redirect. The function makes sure the redirected
|
||||||
* URL is formatted correctly.
|
* URL is formatted correctly.
|
||||||
@@ -785,6 +785,13 @@ function drupal_access_denied() {
|
|||||||
* - data: A string containing the response body that was received.
|
* - data: A string containing the response body that was received.
|
||||||
*/
|
*/
|
||||||
function drupal_http_request($url, array $options = array()) {
|
function drupal_http_request($url, array $options = array()) {
|
||||||
|
// Allow an alternate HTTP client library to replace Drupal's default
|
||||||
|
// implementation.
|
||||||
|
$override_function = variable_get('drupal_http_request_function', FALSE);
|
||||||
|
if (!empty($override_function) && function_exists($override_function)) {
|
||||||
|
return $override_function($url, $options);
|
||||||
|
}
|
||||||
|
|
||||||
$result = new stdClass();
|
$result = new stdClass();
|
||||||
|
|
||||||
// Parse the URL and make sure we can handle the schema.
|
// Parse the URL and make sure we can handle the schema.
|
||||||
@@ -922,7 +929,7 @@ function drupal_http_request($url, array $options = array()) {
|
|||||||
|
|
||||||
// If the server URL has a user then attempt to use basic authentication.
|
// If the server URL has a user then attempt to use basic authentication.
|
||||||
if (isset($uri['user'])) {
|
if (isset($uri['user'])) {
|
||||||
$options['headers']['Authorization'] = 'Basic ' . base64_encode($uri['user'] . (isset($uri['pass']) ? ':' . $uri['pass'] : ''));
|
$options['headers']['Authorization'] = 'Basic ' . base64_encode($uri['user'] . (isset($uri['pass']) ? ':' . $uri['pass'] : ':'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the database prefix is being used by SimpleTest to run the tests in a copied
|
// If the database prefix is being used by SimpleTest to run the tests in a copied
|
||||||
@@ -1127,7 +1134,7 @@ function _fix_gpc_magic(&$item) {
|
|||||||
* @param $key
|
* @param $key
|
||||||
* The key for the item within $_FILES.
|
* The key for the item within $_FILES.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/features.file-upload.php#42280
|
* @see http://php.net/manual/features.file-upload.php#42280
|
||||||
*/
|
*/
|
||||||
function _fix_gpc_magic_files(&$item, $key) {
|
function _fix_gpc_magic_files(&$item, $key) {
|
||||||
if ($key != 'tmp_name') {
|
if ($key != 'tmp_name') {
|
||||||
@@ -1167,7 +1174,8 @@ function fix_gpc_magic() {
|
|||||||
/**
|
/**
|
||||||
* Verifies the syntax of the given e-mail address.
|
* Verifies the syntax of the given e-mail address.
|
||||||
*
|
*
|
||||||
* See @link http://tools.ietf.org/html/rfc5321 RFC 5321 @endlink for details.
|
* This uses the
|
||||||
|
* @link http://php.net/manual/filter.filters.validate.php PHP e-mail validation filter. @endlink
|
||||||
*
|
*
|
||||||
* @param $mail
|
* @param $mail
|
||||||
* A string containing an e-mail address.
|
* A string containing an e-mail address.
|
||||||
@@ -1418,7 +1426,6 @@ function filter_xss_admin($string) {
|
|||||||
* valid UTF-8.
|
* valid UTF-8.
|
||||||
*
|
*
|
||||||
* @see drupal_validate_utf8()
|
* @see drupal_validate_utf8()
|
||||||
* @ingroup sanitization
|
|
||||||
*/
|
*/
|
||||||
function filter_xss($string, $allowed_tags = array('a', 'em', 'strong', 'cite', 'blockquote', 'code', 'ul', 'ol', 'li', 'dl', 'dt', 'dd')) {
|
function filter_xss($string, $allowed_tags = array('a', 'em', 'strong', 'cite', 'blockquote', 'code', 'ul', 'ol', 'li', 'dl', 'dt', 'dd')) {
|
||||||
// Only operate on valid UTF-8 strings. This is necessary to prevent cross
|
// Only operate on valid UTF-8 strings. This is necessary to prevent cross
|
||||||
@@ -1942,7 +1949,7 @@ function format_interval($interval, $granularity = 2, $langcode = NULL) {
|
|||||||
* get interpreted as date format characters.
|
* get interpreted as date format characters.
|
||||||
* @param $timezone
|
* @param $timezone
|
||||||
* (optional) Time zone identifier, as described at
|
* (optional) Time zone identifier, as described at
|
||||||
* http://php.net/manual/en/timezones.php Defaults to the time zone used to
|
* http://php.net/manual/timezones.php Defaults to the time zone used to
|
||||||
* display the page.
|
* display the page.
|
||||||
* @param $langcode
|
* @param $langcode
|
||||||
* (optional) Language code to translate to. Defaults to the language used to
|
* (optional) Language code to translate to. Defaults to the language used to
|
||||||
@@ -2078,6 +2085,9 @@ function _format_date_callback(array $matches = NULL, $new_langcode = NULL) {
|
|||||||
/**
|
/**
|
||||||
* Format a username.
|
* Format a username.
|
||||||
*
|
*
|
||||||
|
* This is also the label callback implementation of
|
||||||
|
* callback_entity_info_label() for user_entity_info().
|
||||||
|
*
|
||||||
* By default, the passed-in object's 'name' property is used if it exists, or
|
* By default, the passed-in object's 'name' property is used if it exists, or
|
||||||
* else, the site-defined value for the 'anonymous' variable. However, a module
|
* else, the site-defined value for the 'anonymous' variable. However, a module
|
||||||
* may override this by implementing hook_username_alter(&$name, $account).
|
* may override this by implementing hook_username_alter(&$name, $account).
|
||||||
@@ -2379,6 +2389,14 @@ function drupal_attributes(array $attributes = array()) {
|
|||||||
* internal links output by modules should be generated by this function if
|
* internal links output by modules should be generated by this function if
|
||||||
* possible.
|
* possible.
|
||||||
*
|
*
|
||||||
|
* However, for links enclosed in translatable text you should use t() and
|
||||||
|
* embed the HTML anchor tag directly in the translated string. For example:
|
||||||
|
* @code
|
||||||
|
* t('Visit the <a href="@url">settings</a> page', array('@url' => url('admin')));
|
||||||
|
* @endcode
|
||||||
|
* This keeps the context of the link title ('settings' in the example) for
|
||||||
|
* translators.
|
||||||
|
*
|
||||||
* @param string $text
|
* @param string $text
|
||||||
* The translated link text for the anchor tag.
|
* The translated link text for the anchor tag.
|
||||||
* @param string $path
|
* @param string $path
|
||||||
@@ -2779,7 +2797,7 @@ function drupal_set_time_limit($time_limit) {
|
|||||||
* The name of the item for which the path is requested.
|
* The name of the item for which the path is requested.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* The path to the requested item.
|
* The path to the requested item or an empty string if the item is not found.
|
||||||
*/
|
*/
|
||||||
function drupal_get_path($type, $name) {
|
function drupal_get_path($type, $name) {
|
||||||
return dirname(drupal_get_filename($type, $name));
|
return dirname(drupal_get_filename($type, $name));
|
||||||
@@ -3654,17 +3672,23 @@ function drupal_load_stylesheet($file, $optimize = NULL, $reset_basepath = TRUE)
|
|||||||
if ($basepath && !file_uri_scheme($file)) {
|
if ($basepath && !file_uri_scheme($file)) {
|
||||||
$file = $basepath . '/' . $file;
|
$file = $basepath . '/' . $file;
|
||||||
}
|
}
|
||||||
|
// Store the parent base path to restore it later.
|
||||||
|
$parent_base_path = $basepath;
|
||||||
|
// Set the current base path to process possible child imports.
|
||||||
$basepath = dirname($file);
|
$basepath = dirname($file);
|
||||||
|
|
||||||
// Load the CSS stylesheet. We suppress errors because themes may specify
|
// Load the CSS stylesheet. We suppress errors because themes may specify
|
||||||
// stylesheets in their .info file that don't exist in the theme's path,
|
// stylesheets in their .info file that don't exist in the theme's path,
|
||||||
// but are merely there to disable certain module CSS files.
|
// but are merely there to disable certain module CSS files.
|
||||||
|
$content = '';
|
||||||
if ($contents = @file_get_contents($file)) {
|
if ($contents = @file_get_contents($file)) {
|
||||||
// Return the processed stylesheet.
|
// Return the processed stylesheet.
|
||||||
return drupal_load_stylesheet_content($contents, $_optimize);
|
$content = drupal_load_stylesheet_content($contents, $_optimize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
// Restore the parent base path as the file and its childen are processed.
|
||||||
|
$basepath = $parent_base_path;
|
||||||
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3681,7 +3705,7 @@ function drupal_load_stylesheet($file, $optimize = NULL, $reset_basepath = TRUE)
|
|||||||
*/
|
*/
|
||||||
function drupal_load_stylesheet_content($contents, $optimize = FALSE) {
|
function drupal_load_stylesheet_content($contents, $optimize = FALSE) {
|
||||||
// Remove multiple charset declarations for standards compliance (and fixing Safari problems).
|
// Remove multiple charset declarations for standards compliance (and fixing Safari problems).
|
||||||
$contents = preg_replace('/^@charset\s+[\'"](\S*)\b[\'"];/i', '', $contents);
|
$contents = preg_replace('/^@charset\s+[\'"](\S*?)\b[\'"];/i', '', $contents);
|
||||||
|
|
||||||
if ($optimize) {
|
if ($optimize) {
|
||||||
// Perform some safe CSS optimizations.
|
// Perform some safe CSS optimizations.
|
||||||
@@ -3700,7 +3724,7 @@ function drupal_load_stylesheet_content($contents, $optimize = FALSE) {
|
|||||||
// Remove certain whitespace.
|
// Remove certain whitespace.
|
||||||
// There are different conditions for removing leading and trailing
|
// There are different conditions for removing leading and trailing
|
||||||
// whitespace.
|
// whitespace.
|
||||||
// @see http://php.net/manual/en/regexp.reference.subpatterns.php
|
// @see http://php.net/manual/regexp.reference.subpatterns.php
|
||||||
$contents = preg_replace('<
|
$contents = preg_replace('<
|
||||||
# Strip leading and trailing whitespace.
|
# Strip leading and trailing whitespace.
|
||||||
\s*([@{};,])\s*
|
\s*([@{};,])\s*
|
||||||
@@ -3814,7 +3838,14 @@ function drupal_clean_css_identifier($identifier, $filter = array(' ' => '-', '_
|
|||||||
* The cleaned class name.
|
* The cleaned class name.
|
||||||
*/
|
*/
|
||||||
function drupal_html_class($class) {
|
function drupal_html_class($class) {
|
||||||
return drupal_clean_css_identifier(drupal_strtolower($class));
|
// The output of this function will never change, so this uses a normal
|
||||||
|
// static instead of drupal_static().
|
||||||
|
static $classes = array();
|
||||||
|
|
||||||
|
if (!isset($classes[$class])) {
|
||||||
|
$classes[$class] = drupal_clean_css_identifier(drupal_strtolower($class));
|
||||||
|
}
|
||||||
|
return $classes[$class];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3869,7 +3900,16 @@ function drupal_html_id($id) {
|
|||||||
// requested id. $_POST['ajax_html_ids'] contains the ids as they were
|
// requested id. $_POST['ajax_html_ids'] contains the ids as they were
|
||||||
// returned by this function, potentially with the appended counter, so
|
// returned by this function, potentially with the appended counter, so
|
||||||
// we parse that to reconstruct the $seen_ids array.
|
// we parse that to reconstruct the $seen_ids array.
|
||||||
foreach ($_POST['ajax_html_ids'] as $seen_id) {
|
if (isset($_POST['ajax_html_ids'][0]) && strpos($_POST['ajax_html_ids'][0], ',') === FALSE) {
|
||||||
|
$ajax_html_ids = $_POST['ajax_html_ids'];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// jquery.form.js may send the server a comma-separated string as the
|
||||||
|
// first element of an array (see http://drupal.org/node/1575060), so
|
||||||
|
// we need to convert it to an array in that case.
|
||||||
|
$ajax_html_ids = explode(',', $_POST['ajax_html_ids'][0]);
|
||||||
|
}
|
||||||
|
foreach ($ajax_html_ids as $seen_id) {
|
||||||
// We rely on '--' being used solely for separating a base id from the
|
// We rely on '--' being used solely for separating a base id from the
|
||||||
// counter, which this function ensures when returning an id.
|
// counter, which this function ensures when returning an id.
|
||||||
$parts = explode('--', $seen_id, 2);
|
$parts = explode('--', $seen_id, 2);
|
||||||
@@ -4069,7 +4109,7 @@ function drupal_region_class($region) {
|
|||||||
* else being the same, JavaScript added by a call to drupal_add_js() that
|
* else being the same, JavaScript added by a call to drupal_add_js() that
|
||||||
* happened later in the page request gets added to the page after one for
|
* happened later in the page request gets added to the page after one for
|
||||||
* which drupal_add_js() happened earlier in the page request.
|
* which drupal_add_js() happened earlier in the page request.
|
||||||
* - defer: If set to TRUE, the defer attribute is set on the <script>
|
* - defer: If set to TRUE, the defer attribute is set on the <script>
|
||||||
* tag. Defaults to FALSE.
|
* tag. Defaults to FALSE.
|
||||||
* - cache: If set to FALSE, the JavaScript file is loaded anew on every page
|
* - cache: If set to FALSE, the JavaScript file is loaded anew on every page
|
||||||
* call; in other words, it is not cached. Used only when 'type' references
|
* call; in other words, it is not cached. Used only when 'type' references
|
||||||
@@ -5006,19 +5046,6 @@ function drupal_json_output($var = NULL) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a salt useful for hardening against SQL injection.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* A salt based on information in settings.php, not in the database.
|
|
||||||
*/
|
|
||||||
function drupal_get_hash_salt() {
|
|
||||||
global $drupal_hash_salt, $databases;
|
|
||||||
// If the $drupal_hash_salt variable is empty, a hash of the serialized
|
|
||||||
// database credentials is used as a fallback salt.
|
|
||||||
return empty($drupal_hash_salt) ? hash('sha256', serialize($databases)) : $drupal_hash_salt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures the private key variable used to generate tokens is set.
|
* Ensures the private key variable used to generate tokens is set.
|
||||||
*
|
*
|
||||||
@@ -5027,7 +5054,7 @@ function drupal_get_hash_salt() {
|
|||||||
*/
|
*/
|
||||||
function drupal_get_private_key() {
|
function drupal_get_private_key() {
|
||||||
if (!($key = variable_get('drupal_private_key', 0))) {
|
if (!($key = variable_get('drupal_private_key', 0))) {
|
||||||
$key = drupal_hash_base64(drupal_random_bytes(55));
|
$key = drupal_random_key();
|
||||||
variable_set('drupal_private_key', $key);
|
variable_set('drupal_private_key', $key);
|
||||||
}
|
}
|
||||||
return $key;
|
return $key;
|
||||||
@@ -5038,6 +5065,18 @@ function drupal_get_private_key() {
|
|||||||
*
|
*
|
||||||
* @param $value
|
* @param $value
|
||||||
* An additional value to base the token on.
|
* An additional value to base the token on.
|
||||||
|
*
|
||||||
|
* The generated token is based on the session ID of the current user. Normally,
|
||||||
|
* anonymous users do not have a session, so the generated token will be
|
||||||
|
* different on every page request. To generate a token for users without a
|
||||||
|
* session, manually start a session prior to calling this function.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* A 43-character URL-safe token for validation, based on the user session ID,
|
||||||
|
* the hash salt provided from drupal_get_hash_salt(), and the
|
||||||
|
* 'drupal_private_key' configuration variable.
|
||||||
|
*
|
||||||
|
* @see drupal_get_hash_salt()
|
||||||
*/
|
*/
|
||||||
function drupal_get_token($value = '') {
|
function drupal_get_token($value = '') {
|
||||||
return drupal_hmac_base64($value, session_id() . drupal_get_private_key() . drupal_get_hash_salt());
|
return drupal_hmac_base64($value, session_id() . drupal_get_private_key() . drupal_get_hash_salt());
|
||||||
@@ -5059,7 +5098,7 @@ function drupal_get_token($value = '') {
|
|||||||
*/
|
*/
|
||||||
function drupal_valid_token($token, $value = '', $skip_anonymous = FALSE) {
|
function drupal_valid_token($token, $value = '', $skip_anonymous = FALSE) {
|
||||||
global $user;
|
global $user;
|
||||||
return (($skip_anonymous && $user->uid == 0) || ($token == drupal_get_token($value)));
|
return (($skip_anonymous && $user->uid == 0) || ($token === drupal_get_token($value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
function _drupal_bootstrap_full() {
|
function _drupal_bootstrap_full() {
|
||||||
@@ -5092,6 +5131,10 @@ function _drupal_bootstrap_full() {
|
|||||||
module_load_all();
|
module_load_all();
|
||||||
// Make sure all stream wrappers are registered.
|
// Make sure all stream wrappers are registered.
|
||||||
file_get_stream_wrappers();
|
file_get_stream_wrappers();
|
||||||
|
// Ensure mt_rand is reseeded, to prevent random values from one page load
|
||||||
|
// being exploited to predict random values in subsequent page loads.
|
||||||
|
$seed = unpack("L", drupal_random_bytes(4));
|
||||||
|
mt_srand($seed[1]);
|
||||||
|
|
||||||
$test_info = &$GLOBALS['drupal_test_info'];
|
$test_info = &$GLOBALS['drupal_test_info'];
|
||||||
if (!empty($test_info['in_child_site'])) {
|
if (!empty($test_info['in_child_site'])) {
|
||||||
@@ -5129,7 +5172,7 @@ function _drupal_bootstrap_full() {
|
|||||||
* client without gzip support.
|
* client without gzip support.
|
||||||
*
|
*
|
||||||
* Page compression requires the PHP zlib extension
|
* Page compression requires the PHP zlib extension
|
||||||
* (http://php.net/manual/en/ref.zlib.php).
|
* (http://php.net/manual/ref.zlib.php).
|
||||||
*
|
*
|
||||||
* @see drupal_page_header()
|
* @see drupal_page_header()
|
||||||
*/
|
*/
|
||||||
@@ -5137,6 +5180,10 @@ function drupal_page_set_cache() {
|
|||||||
global $base_root;
|
global $base_root;
|
||||||
|
|
||||||
if (drupal_page_is_cacheable()) {
|
if (drupal_page_is_cacheable()) {
|
||||||
|
|
||||||
|
// Check whether the current page might be compressed.
|
||||||
|
$page_compressed = variable_get('page_compression', TRUE) && extension_loaded('zlib');
|
||||||
|
|
||||||
$cache = (object) array(
|
$cache = (object) array(
|
||||||
'cid' => $base_root . request_uri(),
|
'cid' => $base_root . request_uri(),
|
||||||
'data' => array(
|
'data' => array(
|
||||||
@@ -5144,6 +5191,9 @@ function drupal_page_set_cache() {
|
|||||||
'body' => ob_get_clean(),
|
'body' => ob_get_clean(),
|
||||||
'title' => drupal_get_title(),
|
'title' => drupal_get_title(),
|
||||||
'headers' => array(),
|
'headers' => array(),
|
||||||
|
// We need to store whether page was compressed or not,
|
||||||
|
// because by the time it is read, the configuration might change.
|
||||||
|
'page_compressed' => $page_compressed,
|
||||||
),
|
),
|
||||||
'expire' => CACHE_TEMPORARY,
|
'expire' => CACHE_TEMPORARY,
|
||||||
'created' => REQUEST_TIME,
|
'created' => REQUEST_TIME,
|
||||||
@@ -5161,7 +5211,7 @@ function drupal_page_set_cache() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($cache->data['body']) {
|
if ($cache->data['body']) {
|
||||||
if (variable_get('page_compression', TRUE) && extension_loaded('zlib')) {
|
if ($page_compressed) {
|
||||||
$cache->data['body'] = gzencode($cache->data['body'], 9, FORCE_GZIP);
|
$cache->data['body'] = gzencode($cache->data['body'], 9, FORCE_GZIP);
|
||||||
}
|
}
|
||||||
cache_set($cache->cid, $cache->data, 'cache_page', $cache->expire);
|
cache_set($cache->cid, $cache->data, 'cache_page', $cache->expire);
|
||||||
@@ -5236,12 +5286,23 @@ function drupal_cron_run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($queues as $queue_name => $info) {
|
foreach ($queues as $queue_name => $info) {
|
||||||
|
if (!empty($info['skip on cron'])) {
|
||||||
|
// Do not run if queue wants to skip.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$function = $info['worker callback'];
|
$function = $info['worker callback'];
|
||||||
$end = time() + (isset($info['time']) ? $info['time'] : 15);
|
$end = time() + (isset($info['time']) ? $info['time'] : 15);
|
||||||
$queue = DrupalQueue::get($queue_name);
|
$queue = DrupalQueue::get($queue_name);
|
||||||
while (time() < $end && ($item = $queue->claimItem())) {
|
while (time() < $end && ($item = $queue->claimItem())) {
|
||||||
$function($item->data);
|
try {
|
||||||
$queue->deleteItem($item);
|
$function($item->data);
|
||||||
|
$queue->deleteItem($item);
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
// In case of exception log it and leave the item in the queue
|
||||||
|
// to be processed again later.
|
||||||
|
watchdog_exception('cron', $e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Restore the user.
|
// Restore the user.
|
||||||
@@ -5568,7 +5629,7 @@ function drupal_pre_render_link($element) {
|
|||||||
* @code
|
* @code
|
||||||
* $node->content['links'] = array(
|
* $node->content['links'] = array(
|
||||||
* '#theme' => 'links__node',
|
* '#theme' => 'links__node',
|
||||||
* '#pre_render' = array('drupal_pre_render_links'),
|
* '#pre_render' => array('drupal_pre_render_links'),
|
||||||
* 'comment' => array(
|
* 'comment' => array(
|
||||||
* '#theme' => 'links__node__comment',
|
* '#theme' => 'links__node__comment',
|
||||||
* '#links' => array(
|
* '#links' => array(
|
||||||
@@ -5773,23 +5834,23 @@ function drupal_render_page($page) {
|
|||||||
* array to be rendered independently and prevents them from being rendered
|
* array to be rendered independently and prevents them from being rendered
|
||||||
* more than once on subsequent calls to drupal_render() (e.g., as part of a
|
* more than once on subsequent calls to drupal_render() (e.g., as part of a
|
||||||
* larger array). If the same array or array element is passed more than once
|
* larger array). If the same array or array element is passed more than once
|
||||||
* to drupal_render(), it simply returns a NULL value.
|
* to drupal_render(), it simply returns an empty string.
|
||||||
*
|
*
|
||||||
* @param $elements
|
* @param array $elements
|
||||||
* The structured array describing the data to be rendered.
|
* The structured array describing the data to be rendered.
|
||||||
*
|
*
|
||||||
* @return
|
* @return string
|
||||||
* The rendered HTML.
|
* The rendered HTML.
|
||||||
*/
|
*/
|
||||||
function drupal_render(&$elements) {
|
function drupal_render(&$elements) {
|
||||||
// Early-return nothing if user does not have access.
|
// Early-return nothing if user does not have access.
|
||||||
if (empty($elements) || (isset($elements['#access']) && !$elements['#access'])) {
|
if (empty($elements) || (isset($elements['#access']) && !$elements['#access'])) {
|
||||||
return;
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not print elements twice.
|
// Do not print elements twice.
|
||||||
if (!empty($elements['#printed'])) {
|
if (!empty($elements['#printed'])) {
|
||||||
return;
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to fetch the element's markup from cache and return.
|
// Try to fetch the element's markup from cache and return.
|
||||||
@@ -5825,7 +5886,7 @@ function drupal_render(&$elements) {
|
|||||||
|
|
||||||
// Allow #pre_render to abort rendering.
|
// Allow #pre_render to abort rendering.
|
||||||
if (!empty($elements['#printed'])) {
|
if (!empty($elements['#printed'])) {
|
||||||
return;
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the children of the element, sorted by weight.
|
// Get the children of the element, sorted by weight.
|
||||||
@@ -5896,14 +5957,16 @@ function drupal_render(&$elements) {
|
|||||||
/**
|
/**
|
||||||
* Renders children of an element and concatenates them.
|
* Renders children of an element and concatenates them.
|
||||||
*
|
*
|
||||||
* This renders all children of an element using drupal_render() and then
|
* @param array $element
|
||||||
* joins them together into a single string.
|
|
||||||
*
|
|
||||||
* @param $element
|
|
||||||
* The structured array whose children shall be rendered.
|
* The structured array whose children shall be rendered.
|
||||||
* @param $children_keys
|
* @param array $children_keys
|
||||||
* If the keys of the element's children are already known, they can be passed
|
* (optional) If the keys of the element's children are already known, they
|
||||||
* in to save another run of element_children().
|
* can be passed in to save another run of element_children().
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The rendered HTML of all children of the element.
|
||||||
|
|
||||||
|
* @see drupal_render()
|
||||||
*/
|
*/
|
||||||
function drupal_render_children(&$element, $children_keys = NULL) {
|
function drupal_render_children(&$element, $children_keys = NULL) {
|
||||||
if ($children_keys === NULL) {
|
if ($children_keys === NULL) {
|
||||||
@@ -6447,6 +6510,44 @@ function element_set_attributes(array &$element, array $map) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively computes the difference of arrays with additional index check.
|
||||||
|
*
|
||||||
|
* This is a version of array_diff_assoc() that supports multidimensional
|
||||||
|
* arrays.
|
||||||
|
*
|
||||||
|
* @param array $array1
|
||||||
|
* The array to compare from.
|
||||||
|
* @param array $array2
|
||||||
|
* The array to compare to.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* Returns an array containing all the values from array1 that are not present
|
||||||
|
* in array2.
|
||||||
|
*/
|
||||||
|
function drupal_array_diff_assoc_recursive($array1, $array2) {
|
||||||
|
$difference = array();
|
||||||
|
|
||||||
|
foreach ($array1 as $key => $value) {
|
||||||
|
if (is_array($value)) {
|
||||||
|
if (!array_key_exists($key, $array2) || !is_array($array2[$key])) {
|
||||||
|
$difference[$key] = $value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$new_diff = drupal_array_diff_assoc_recursive($value, $array2[$key]);
|
||||||
|
if (!empty($new_diff)) {
|
||||||
|
$difference[$key] = $new_diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif (!array_key_exists($key, $array2) || $array2[$key] !== $value) {
|
||||||
|
$difference[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $difference;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a value in a nested array with variable depth.
|
* Sets a value in a nested array with variable depth.
|
||||||
*
|
*
|
||||||
@@ -7739,7 +7840,10 @@ function entity_load_unchanged($entity_type, $id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the entity controller class for an entity type.
|
* Gets the entity controller for an entity type.
|
||||||
|
*
|
||||||
|
* @return DrupalEntityControllerInterface
|
||||||
|
* The entity controller object for the specified entity type.
|
||||||
*/
|
*/
|
||||||
function entity_get_controller($entity_type) {
|
function entity_get_controller($entity_type) {
|
||||||
$controllers = &drupal_static(__FUNCTION__, array());
|
$controllers = &drupal_static(__FUNCTION__, array());
|
||||||
|
|||||||
@@ -28,18 +28,21 @@
|
|||||||
* Most Drupal database SELECT queries are performed by a call to db_query() or
|
* Most Drupal database SELECT queries are performed by a call to db_query() or
|
||||||
* db_query_range(). Module authors should also consider using the PagerDefault
|
* db_query_range(). Module authors should also consider using the PagerDefault
|
||||||
* Extender for queries that return results that need to be presented on
|
* Extender for queries that return results that need to be presented on
|
||||||
* multiple pages, and the Tablesort Extender for generating appropriate queries
|
* multiple pages (see https://drupal.org/node/508796), and the TableSort
|
||||||
* for sortable tables.
|
* Extender for generating appropriate queries for sortable tables
|
||||||
|
* (see https://drupal.org/node/1848372).
|
||||||
*
|
*
|
||||||
* For example, one might wish to return a list of the most recent 10 nodes
|
* For example, one might wish to return a list of the most recent 10 nodes
|
||||||
* authored by a given user. Instead of directly issuing the SQL query
|
* authored by a given user. Instead of directly issuing the SQL query
|
||||||
* @code
|
* @code
|
||||||
* SELECT n.nid, n.title, n.created FROM node n WHERE n.uid = $uid LIMIT 0, 10;
|
* SELECT n.nid, n.title, n.created FROM node n WHERE n.uid = $uid
|
||||||
|
* ORDER BY n.created DESC LIMIT 0, 10;
|
||||||
* @endcode
|
* @endcode
|
||||||
* one would instead call the Drupal functions:
|
* one would instead call the Drupal functions:
|
||||||
* @code
|
* @code
|
||||||
* $result = db_query_range('SELECT n.nid, n.title, n.created
|
* $result = db_query_range('SELECT n.nid, n.title, n.created
|
||||||
* FROM {node} n WHERE n.uid = :uid', 0, 10, array(':uid' => $uid));
|
* FROM {node} n WHERE n.uid = :uid
|
||||||
|
* ORDER BY n.created DESC', 0, 10, array(':uid' => $uid));
|
||||||
* foreach ($result as $record) {
|
* foreach ($result as $record) {
|
||||||
* // Perform operations on $record->title, etc. here.
|
* // Perform operations on $record->title, etc. here.
|
||||||
* }
|
* }
|
||||||
@@ -167,7 +170,7 @@
|
|||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*
|
*
|
||||||
* @link http://drupal.org/developing/api/database @endlink
|
* @see http://drupal.org/developing/api/database
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -179,7 +182,7 @@
|
|||||||
* concrete implementation of it to support special handling required by that
|
* concrete implementation of it to support special handling required by that
|
||||||
* database.
|
* database.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/book.pdo.php
|
* @see http://php.net/manual/book.pdo.php
|
||||||
*/
|
*/
|
||||||
abstract class DatabaseConnection extends PDO {
|
abstract class DatabaseConnection extends PDO {
|
||||||
|
|
||||||
@@ -194,7 +197,7 @@ abstract class DatabaseConnection extends PDO {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The key representing this connection.
|
* The key representing this connection.
|
||||||
*
|
*
|
||||||
* The key is a unique string which identifies a database connection. A
|
* The key is a unique string which identifies a database connection. A
|
||||||
* connection can be a single server or a cluster of master and slaves (use
|
* connection can be a single server or a cluster of master and slaves (use
|
||||||
* target to pick between master and slave).
|
* target to pick between master and slave).
|
||||||
@@ -303,12 +306,28 @@ abstract class DatabaseConnection extends PDO {
|
|||||||
// Call PDO::__construct and PDO::setAttribute.
|
// Call PDO::__construct and PDO::setAttribute.
|
||||||
parent::__construct($dsn, $username, $password, $driver_options);
|
parent::__construct($dsn, $username, $password, $driver_options);
|
||||||
|
|
||||||
// Set a specific PDOStatement class if the driver requires that.
|
// Set a Statement class, unless the driver opted out.
|
||||||
if (!empty($this->statementClass)) {
|
if (!empty($this->statementClass)) {
|
||||||
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array($this->statementClass, array($this)));
|
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array($this->statementClass, array($this)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys this Connection object.
|
||||||
|
*
|
||||||
|
* PHP does not destruct an object if it is still referenced in other
|
||||||
|
* variables. In case of PDO database connection objects, PHP only closes the
|
||||||
|
* connection when the PDO object is destructed, so any references to this
|
||||||
|
* object may cause the number of maximum allowed connections to be exceeded.
|
||||||
|
*/
|
||||||
|
public function destroy() {
|
||||||
|
// Destroy all references to this connection by setting them to NULL.
|
||||||
|
// The Statement class attribute only accepts a new value that presents a
|
||||||
|
// proper callable, so we reset it to PDOStatement.
|
||||||
|
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('PDOStatement', array()));
|
||||||
|
$this->schema = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the default query options for any given query.
|
* Returns the default query options for any given query.
|
||||||
*
|
*
|
||||||
@@ -1627,8 +1646,8 @@ abstract class Database {
|
|||||||
*/
|
*/
|
||||||
final public static function removeConnection($key) {
|
final public static function removeConnection($key) {
|
||||||
if (isset(self::$databaseInfo[$key])) {
|
if (isset(self::$databaseInfo[$key])) {
|
||||||
|
self::closeConnection(NULL, $key);
|
||||||
unset(self::$databaseInfo[$key]);
|
unset(self::$databaseInfo[$key]);
|
||||||
unset(self::$connections[$key]);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1694,11 +1713,24 @@ abstract class Database {
|
|||||||
if (!isset($key)) {
|
if (!isset($key)) {
|
||||||
$key = self::$activeKey;
|
$key = self::$activeKey;
|
||||||
}
|
}
|
||||||
// To close the connection, we need to unset the static variable.
|
// To close a connection, it needs to be set to NULL and removed from the
|
||||||
|
// static variable. In all cases, closeConnection() might be called for a
|
||||||
|
// connection that was not opened yet, in which case the key is not defined
|
||||||
|
// yet and we just ensure that the connection key is undefined.
|
||||||
if (isset($target)) {
|
if (isset($target)) {
|
||||||
|
if (isset(self::$connections[$key][$target])) {
|
||||||
|
self::$connections[$key][$target]->destroy();
|
||||||
|
self::$connections[$key][$target] = NULL;
|
||||||
|
}
|
||||||
unset(self::$connections[$key][$target]);
|
unset(self::$connections[$key][$target]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (isset(self::$connections[$key])) {
|
||||||
|
foreach (self::$connections[$key] as $target => $connection) {
|
||||||
|
self::$connections[$key][$target]->destroy();
|
||||||
|
self::$connections[$key][$target] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
unset(self::$connections[$key]);
|
unset(self::$connections[$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1852,8 +1884,8 @@ class DatabaseTransaction {
|
|||||||
*/
|
*/
|
||||||
protected $name;
|
protected $name;
|
||||||
|
|
||||||
public function __construct(DatabaseConnection &$connection, $name = NULL) {
|
public function __construct(DatabaseConnection $connection, $name = NULL) {
|
||||||
$this->connection = &$connection;
|
$this->connection = $connection;
|
||||||
// If there is no transaction depth, then no transaction has started. Name
|
// If there is no transaction depth, then no transaction has started. Name
|
||||||
// the transaction 'drupal_transaction'.
|
// the transaction 'drupal_transaction'.
|
||||||
if (!$depth = $connection->transactionDepth()) {
|
if (!$depth = $connection->transactionDepth()) {
|
||||||
@@ -1957,7 +1989,7 @@ interface DatabaseStatementInterface extends Traversable {
|
|||||||
/**
|
/**
|
||||||
* Sets the default fetch mode for this statement.
|
* Sets the default fetch mode for this statement.
|
||||||
*
|
*
|
||||||
* See http://php.net/manual/en/pdo.constants.php for the definition of the
|
* See http://php.net/manual/pdo.constants.php for the definition of the
|
||||||
* constants used.
|
* constants used.
|
||||||
*
|
*
|
||||||
* @param $mode
|
* @param $mode
|
||||||
@@ -1976,7 +2008,7 @@ interface DatabaseStatementInterface extends Traversable {
|
|||||||
/**
|
/**
|
||||||
* Fetches the next row from a result set.
|
* Fetches the next row from a result set.
|
||||||
*
|
*
|
||||||
* See http://php.net/manual/en/pdo.constants.php for the definition of the
|
* See http://php.net/manual/pdo.constants.php for the definition of the
|
||||||
* constants used.
|
* constants used.
|
||||||
*
|
*
|
||||||
* @param $mode
|
* @param $mode
|
||||||
@@ -2351,14 +2383,14 @@ function db_query_range($query, $from, $count, array $args = array(), array $opt
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes a query string and saves the result set to a temporary table.
|
* Executes a SELECT query string and saves the result set to a temporary table.
|
||||||
*
|
*
|
||||||
* The execution of the query string happens against the active database.
|
* The execution of the query string happens against the active database.
|
||||||
*
|
*
|
||||||
* @param $query
|
* @param $query
|
||||||
* The prepared statement query to run. Although it will accept both named and
|
* The prepared SELECT statement query to run. Although it will accept both
|
||||||
* unnamed placeholders, named placeholders are strongly preferred as they are
|
* named and unnamed placeholders, named placeholders are strongly preferred
|
||||||
* more self-documenting.
|
* as they are more self-documenting.
|
||||||
* @param $args
|
* @param $args
|
||||||
* An array of values to substitute into the query. If the query uses named
|
* An array of values to substitute into the query. If the query uses named
|
||||||
* placeholders, this is an associative array in any order. If the query uses
|
* placeholders, this is an associative array in any order. If the query uses
|
||||||
|
|||||||
@@ -13,11 +13,11 @@
|
|||||||
class DatabaseConnection_mysql extends DatabaseConnection {
|
class DatabaseConnection_mysql extends DatabaseConnection {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag to indicate if we have registered the nextID cleanup function.
|
* Flag to indicate if the cleanup function in __destruct() should run.
|
||||||
*
|
*
|
||||||
* @var boolean
|
* @var boolean
|
||||||
*/
|
*/
|
||||||
protected $shutdownRegistered = FALSE;
|
protected $needsCleanup = FALSE;
|
||||||
|
|
||||||
public function __construct(array $connection_options = array()) {
|
public function __construct(array $connection_options = array()) {
|
||||||
// This driver defaults to transaction support, except if explicitly passed FALSE.
|
// This driver defaults to transaction support, except if explicitly passed FALSE.
|
||||||
@@ -78,13 +78,19 @@ class DatabaseConnection_mysql extends DatabaseConnection {
|
|||||||
$this->exec(implode('; ', $connection_options['init_commands']));
|
$this->exec(implode('; ', $connection_options['init_commands']));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __destruct() {
|
||||||
|
if ($this->needsCleanup) {
|
||||||
|
$this->nextIdDelete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function queryRange($query, $from, $count, array $args = array(), array $options = array()) {
|
public function queryRange($query, $from, $count, array $args = array(), array $options = array()) {
|
||||||
return $this->query($query . ' LIMIT ' . (int) $from . ', ' . (int) $count, $args, $options);
|
return $this->query($query . ' LIMIT ' . (int) $from . ', ' . (int) $count, $args, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function queryTemporary($query, array $args = array(), array $options = array()) {
|
public function queryTemporary($query, array $args = array(), array $options = array()) {
|
||||||
$tablename = $this->generateTemporaryTableName();
|
$tablename = $this->generateTemporaryTableName();
|
||||||
$this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE {' . $tablename . '} Engine=MEMORY SELECT', $query), $args, $options);
|
$this->query('CREATE TEMPORARY TABLE {' . $tablename . '} Engine=MEMORY ' . $query, $args, $options);
|
||||||
return $tablename;
|
return $tablename;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,12 +121,7 @@ class DatabaseConnection_mysql extends DatabaseConnection {
|
|||||||
$this->query('INSERT INTO {sequences} (value) VALUES (:value) ON DUPLICATE KEY UPDATE value = value', array(':value' => $existing_id));
|
$this->query('INSERT INTO {sequences} (value) VALUES (:value) ON DUPLICATE KEY UPDATE value = value', array(':value' => $existing_id));
|
||||||
$new_id = $this->query('INSERT INTO {sequences} () VALUES ()', array(), array('return' => Database::RETURN_INSERT_ID));
|
$new_id = $this->query('INSERT INTO {sequences} () VALUES ()', array(), array('return' => Database::RETURN_INSERT_ID));
|
||||||
}
|
}
|
||||||
if (!$this->shutdownRegistered) {
|
$this->needsCleanup = TRUE;
|
||||||
// Use register_shutdown_function() here to keep the database system
|
|
||||||
// independent of Drupal.
|
|
||||||
register_shutdown_function(array($this, 'nextIdDelete'));
|
|
||||||
$shutdownRegistered = TRUE;
|
|
||||||
}
|
|
||||||
return $new_id;
|
return $new_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ class InsertQuery_mysql extends InsertQuery {
|
|||||||
// If we're selecting from a SelectQuery, finish building the query and
|
// If we're selecting from a SelectQuery, finish building the query and
|
||||||
// pass it back, as any remaining options are irrelevant.
|
// pass it back, as any remaining options are irrelevant.
|
||||||
if (!empty($this->fromQuery)) {
|
if (!empty($this->fromQuery)) {
|
||||||
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') ' . $this->fromQuery;
|
$insert_fields_string = $insert_fields ? ' (' . implode(', ', $insert_fields) . ') ' : ' ';
|
||||||
|
return $comments . 'INSERT INTO {' . $this->table . '}' . $insert_fields_string . $this->fromQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';
|
$query = $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';
|
||||||
@@ -86,21 +87,7 @@ class InsertQuery_mysql extends InsertQuery {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TruncateQuery_mysql extends TruncateQuery {
|
class TruncateQuery_mysql extends TruncateQuery { }
|
||||||
public function __toString() {
|
|
||||||
// TRUNCATE is actually a DDL statement on MySQL, and DDL statements are
|
|
||||||
// not transactional, and result in an implicit COMMIT. When we are in a
|
|
||||||
// transaction, fallback to the slower, but transactional, DELETE.
|
|
||||||
if ($this->connection->inTransaction()) {
|
|
||||||
// Create a comment string to prepend to the query.
|
|
||||||
$comments = $this->connection->makeComment($this->comments);
|
|
||||||
return $comments . 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '}';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return parent::__toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @} End of "addtogroup database".
|
* @} End of "addtogroup database".
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
|
|||||||
|
|
||||||
public function queryTemporary($query, array $args = array(), array $options = array()) {
|
public function queryTemporary($query, array $args = array(), array $options = array()) {
|
||||||
$tablename = $this->generateTemporaryTableName();
|
$tablename = $this->generateTemporaryTableName();
|
||||||
$this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE {' . $tablename . '} AS SELECT', $query), $args, $options);
|
$this->query('CREATE TEMPORARY TABLE {' . $tablename . '} AS ' . $query, $args, $options);
|
||||||
return $tablename;
|
return $tablename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,8 @@ class InsertQuery_pgsql extends InsertQuery {
|
|||||||
// If we're selecting from a SelectQuery, finish building the query and
|
// If we're selecting from a SelectQuery, finish building the query and
|
||||||
// pass it back, as any remaining options are irrelevant.
|
// pass it back, as any remaining options are irrelevant.
|
||||||
if (!empty($this->fromQuery)) {
|
if (!empty($this->fromQuery)) {
|
||||||
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') ' . $this->fromQuery;
|
$insert_fields_string = $insert_fields ? ' (' . implode(', ', $insert_fields) . ') ' : ' ';
|
||||||
|
return $comments . 'INSERT INTO {' . $this->table . '}' . $insert_fields_string . $this->fromQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';
|
$query = $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ interface QueryConditionInterface {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a condition that the specified subquery returns values.
|
* Sets a condition that the specified subquery returns values.
|
||||||
*
|
*
|
||||||
* @param SelectQueryInterface $select
|
* @param SelectQueryInterface $select
|
||||||
* The subquery that must contain results.
|
* The subquery that must contain results.
|
||||||
*
|
*
|
||||||
@@ -91,10 +91,10 @@ interface QueryConditionInterface {
|
|||||||
* The called object.
|
* The called object.
|
||||||
*/
|
*/
|
||||||
public function exists(SelectQueryInterface $select);
|
public function exists(SelectQueryInterface $select);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a condition that the specified subquery returns no values.
|
* Sets a condition that the specified subquery returns no values.
|
||||||
*
|
*
|
||||||
* @param SelectQueryInterface $select
|
* @param SelectQueryInterface $select
|
||||||
* The subquery that must not contain results.
|
* The subquery that must not contain results.
|
||||||
*
|
*
|
||||||
@@ -102,7 +102,7 @@ interface QueryConditionInterface {
|
|||||||
* The called object.
|
* The called object.
|
||||||
*/
|
*/
|
||||||
public function notExists(SelectQueryInterface $select);
|
public function notExists(SelectQueryInterface $select);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a complete list of all conditions in this conditional clause.
|
* Gets a complete list of all conditions in this conditional clause.
|
||||||
*
|
*
|
||||||
@@ -283,14 +283,14 @@ abstract class Query implements QueryPlaceholderInterface {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The target of the connection object.
|
* The target of the connection object.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $connectionTarget;
|
protected $connectionTarget;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The key of the connection object.
|
* The key of the connection object.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $connectionKey;
|
protected $connectionKey;
|
||||||
@@ -710,10 +710,11 @@ class InsertQuery extends Query {
|
|||||||
// first call to fields() does have an effect.
|
// first call to fields() does have an effect.
|
||||||
$this->fields(array_merge(array_keys($this->fromQuery->getFields()), array_keys($this->fromQuery->getExpressions())));
|
$this->fields(array_merge(array_keys($this->fromQuery->getFields()), array_keys($this->fromQuery->getExpressions())));
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
// Don't execute query without fields.
|
// Don't execute query without fields.
|
||||||
if (count($this->insertFields) + count($this->defaultFields) == 0) {
|
if (count($this->insertFields) + count($this->defaultFields) == 0) {
|
||||||
throw new NoFieldsException('There are no fields available to insert with.');
|
throw new NoFieldsException('There are no fields available to insert with.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no values have been added, silently ignore this query. This can happen
|
// If no values have been added, silently ignore this query. This can happen
|
||||||
@@ -804,7 +805,7 @@ class DeleteQuery extends Query implements QueryConditionInterface {
|
|||||||
$this->condition->notExists($select);
|
$this->condition->notExists($select);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements QueryConditionInterface::conditions().
|
* Implements QueryConditionInterface::conditions().
|
||||||
*/
|
*/
|
||||||
@@ -942,7 +943,17 @@ class TruncateQuery extends Query {
|
|||||||
// Create a sanitized comment string to prepend to the query.
|
// Create a sanitized comment string to prepend to the query.
|
||||||
$comments = $this->connection->makeComment($this->comments);
|
$comments = $this->connection->makeComment($this->comments);
|
||||||
|
|
||||||
return $comments . 'TRUNCATE {' . $this->connection->escapeTable($this->table) . '} ';
|
// In most cases, TRUNCATE is not a transaction safe statement as it is a
|
||||||
|
// DDL statement which results in an implicit COMMIT. When we are in a
|
||||||
|
// transaction, fallback to the slower, but transactional, DELETE.
|
||||||
|
// PostgreSQL also locks the entire table for a TRUNCATE strongly reducing
|
||||||
|
// the concurrency with other transactions.
|
||||||
|
if ($this->connection->inTransaction()) {
|
||||||
|
return $comments . 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '}';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return $comments . 'TRUNCATE {' . $this->connection->escapeTable($this->table) . '} ';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1053,7 +1064,7 @@ class UpdateQuery extends Query implements QueryConditionInterface {
|
|||||||
$this->condition->notExists($select);
|
$this->condition->notExists($select);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements QueryConditionInterface::conditions().
|
* Implements QueryConditionInterface::conditions().
|
||||||
*/
|
*/
|
||||||
@@ -1545,7 +1556,7 @@ class MergeQuery extends Query implements QueryConditionInterface {
|
|||||||
$this->condition->notExists($select);
|
$this->condition->notExists($select);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements QueryConditionInterface::conditions().
|
* Implements QueryConditionInterface::conditions().
|
||||||
*/
|
*/
|
||||||
@@ -1595,55 +1606,43 @@ class MergeQuery extends Query implements QueryConditionInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function execute() {
|
public function execute() {
|
||||||
// Wrap multiple queries in a transaction, if the database supports it.
|
if (!count($this->condition)) {
|
||||||
$transaction = $this->connection->startTransaction();
|
throw new InvalidMergeQueryException(t('Invalid merge query: no conditions'));
|
||||||
try {
|
}
|
||||||
if (!count($this->condition)) {
|
$select = $this->connection->select($this->conditionTable)
|
||||||
throw new InvalidMergeQueryException(t('Invalid merge query: no conditions'));
|
->condition($this->condition);
|
||||||
|
$select->addExpression('1');
|
||||||
|
if (!$select->execute()->fetchField()) {
|
||||||
|
try {
|
||||||
|
$insert = $this->connection->insert($this->table)->fields($this->insertFields);
|
||||||
|
if ($this->defaultFields) {
|
||||||
|
$insert->useDefaults($this->defaultFields);
|
||||||
|
}
|
||||||
|
$insert->execute();
|
||||||
|
return self::STATUS_INSERT;
|
||||||
}
|
}
|
||||||
$select = $this->connection->select($this->conditionTable)
|
catch (Exception $e) {
|
||||||
->condition($this->condition)
|
// The insert query failed, maybe it's because a racing insert query
|
||||||
->forUpdate();
|
// beat us in inserting the same row. Retry the select query, if it
|
||||||
$select->addExpression('1');
|
// returns a row, ignore the error and continue with the update
|
||||||
if (!$select->execute()->fetchField()) {
|
// query below.
|
||||||
try {
|
if (!$select->execute()->fetchField()) {
|
||||||
$insert = $this->connection->insert($this->table)->fields($this->insertFields);
|
throw $e;
|
||||||
if ($this->defaultFields) {
|
|
||||||
$insert->useDefaults($this->defaultFields);
|
|
||||||
}
|
|
||||||
$insert->execute();
|
|
||||||
return MergeQuery::STATUS_INSERT;
|
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
|
||||||
// The insert query failed, maybe it's because a racing insert query
|
|
||||||
// beat us in inserting the same row. Retry the select query, if it
|
|
||||||
// returns a row, ignore the error and continue with the update
|
|
||||||
// query below.
|
|
||||||
if (!$select->execute()->fetchField()) {
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($this->needsUpdate) {
|
|
||||||
$update = $this->connection->update($this->table)
|
|
||||||
->fields($this->updateFields)
|
|
||||||
->condition($this->condition);
|
|
||||||
if ($this->expressionFields) {
|
|
||||||
foreach ($this->expressionFields as $field => $data) {
|
|
||||||
$update->expression($field, $data['expression'], $data['arguments']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$update->execute();
|
|
||||||
return MergeQuery::STATUS_UPDATE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
if ($this->needsUpdate) {
|
||||||
// Something really wrong happened here, bubble up the exception to the
|
$update = $this->connection->update($this->table)
|
||||||
// caller.
|
->fields($this->updateFields)
|
||||||
$transaction->rollback();
|
->condition($this->condition);
|
||||||
throw $e;
|
if ($this->expressionFields) {
|
||||||
}
|
foreach ($this->expressionFields as $field => $data) {
|
||||||
// Transaction commits here where $transaction looses scope.
|
$update->expression($field, $data['expression'], $data['arguments']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$update->execute();
|
||||||
|
return self::STATUS_UPDATE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1762,14 +1761,14 @@ class DatabaseCondition implements QueryConditionInterface, Countable {
|
|||||||
public function exists(SelectQueryInterface $select) {
|
public function exists(SelectQueryInterface $select) {
|
||||||
return $this->condition('', $select, 'EXISTS');
|
return $this->condition('', $select, 'EXISTS');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements QueryConditionInterface::notExists().
|
* Implements QueryConditionInterface::notExists().
|
||||||
*/
|
*/
|
||||||
public function notExists(SelectQueryInterface $select) {
|
public function notExists(SelectQueryInterface $select) {
|
||||||
return $this->condition('', $select, 'NOT EXISTS');
|
return $this->condition('', $select, 'NOT EXISTS');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements QueryConditionInterface::conditions().
|
* Implements QueryConditionInterface::conditions().
|
||||||
*/
|
*/
|
||||||
@@ -1898,8 +1897,13 @@ class DatabaseCondition implements QueryConditionInterface, Countable {
|
|||||||
function __clone() {
|
function __clone() {
|
||||||
$this->changed = TRUE;
|
$this->changed = TRUE;
|
||||||
foreach ($this->conditions as $key => $condition) {
|
foreach ($this->conditions as $key => $condition) {
|
||||||
if ($key !== '#conjunction' && $condition['field'] instanceOf QueryConditionInterface) {
|
if ($key !== '#conjunction') {
|
||||||
$this->conditions[$key]['field'] = clone($condition['field']);
|
if ($condition['field'] instanceOf QueryConditionInterface) {
|
||||||
|
$this->conditions[$key]['field'] = clone($condition['field']);
|
||||||
|
}
|
||||||
|
if ($condition['value'] instanceOf SelectQueryInterface) {
|
||||||
|
$this->conditions[$key]['value'] = clone($condition['value']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -596,7 +596,7 @@ class SelectQueryExtender implements SelectQueryInterface {
|
|||||||
|
|
||||||
public function hasAnyTag() {
|
public function hasAnyTag() {
|
||||||
$args = func_get_args();
|
$args = func_get_args();
|
||||||
return call_user_func_array(array($this->query, 'hasAnyTags'), $args);
|
return call_user_func_array(array($this->query, 'hasAnyTag'), $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addMetaData($key, $object) {
|
public function addMetaData($key, $object) {
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
|
|||||||
$prefixes[$tablename] = '';
|
$prefixes[$tablename] = '';
|
||||||
$this->setPrefix($prefixes);
|
$this->setPrefix($prefixes);
|
||||||
|
|
||||||
$this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE ' . $tablename . ' AS SELECT', $query), $args, $options);
|
$this->query('CREATE TEMPORARY TABLE ' . $tablename . ' AS ' . $query, $args, $options);
|
||||||
return $tablename;
|
return $tablename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ class InsertQuery_sqlite extends InsertQuery {
|
|||||||
// If we're selecting from a SelectQuery, finish building the query and
|
// If we're selecting from a SelectQuery, finish building the query and
|
||||||
// pass it back, as any remaining options are irrelevant.
|
// pass it back, as any remaining options are irrelevant.
|
||||||
if (!empty($this->fromQuery)) {
|
if (!empty($this->fromQuery)) {
|
||||||
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $this->insertFields) . ') ' . $this->fromQuery;
|
$insert_fields_string = $this->insertFields ? ' (' . implode(', ', $this->insertFields) . ') ' : ' ';
|
||||||
|
return $comments . 'INSERT INTO {' . $this->table . '}' . $insert_fields_string . $this->fromQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $this->insertFields) . ') VALUES (' . implode(', ', $placeholders) . ')';
|
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $this->insertFields) . ') VALUES (' . implode(', ', $placeholders) . ')';
|
||||||
@@ -57,39 +58,18 @@ class InsertQuery_sqlite extends InsertQuery {
|
|||||||
* we don't select those rows.
|
* we don't select those rows.
|
||||||
*
|
*
|
||||||
* A query like this one:
|
* A query like this one:
|
||||||
* UPDATE test SET name = 'newname' WHERE tid = 1
|
* UPDATE test SET col1 = 'newcol1', col2 = 'newcol2' WHERE tid = 1
|
||||||
* will become:
|
* will become:
|
||||||
* UPDATE test SET name = 'newname' WHERE tid = 1 AND name <> 'newname'
|
* UPDATE test SET col1 = 'newcol1', col2 = 'newcol2' WHERE tid = 1 AND (col1 <> 'newcol1' OR col2 <> 'newcol2')
|
||||||
*/
|
*/
|
||||||
class UpdateQuery_sqlite extends UpdateQuery {
|
class UpdateQuery_sqlite extends UpdateQuery {
|
||||||
/**
|
|
||||||
* Helper function that removes the fields that are already in a condition.
|
|
||||||
*
|
|
||||||
* @param $fields
|
|
||||||
* The fields.
|
|
||||||
* @param QueryConditionInterface $condition
|
|
||||||
* A database condition.
|
|
||||||
*/
|
|
||||||
protected function removeFieldsInCondition(&$fields, QueryConditionInterface $condition) {
|
|
||||||
foreach ($condition->conditions() as $child_condition) {
|
|
||||||
if ($child_condition['field'] instanceof QueryConditionInterface) {
|
|
||||||
$this->removeFieldsInCondition($fields, $child_condition['field']);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
unset($fields[$child_condition['field']]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function execute() {
|
public function execute() {
|
||||||
if (!empty($this->queryOptions['sqlite_return_matched_rows'])) {
|
if (!empty($this->queryOptions['sqlite_return_matched_rows'])) {
|
||||||
return parent::execute();
|
return parent::execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the fields used in the update query, and remove those that are already
|
// Get the fields used in the update query.
|
||||||
// in the condition.
|
|
||||||
$fields = $this->expressionFields + $this->fields;
|
$fields = $this->expressionFields + $this->fields;
|
||||||
$this->removeFieldsInCondition($fields, $this->condition);
|
|
||||||
|
|
||||||
// Add the inverse of the fields to the condition.
|
// Add the inverse of the fields to the condition.
|
||||||
$condition = new DatabaseCondition('OR');
|
$condition = new DatabaseCondition('OR');
|
||||||
|
|||||||
@@ -13,14 +13,6 @@
|
|||||||
*/
|
*/
|
||||||
interface DrupalEntityControllerInterface {
|
interface DrupalEntityControllerInterface {
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param $entityType
|
|
||||||
* The entity type for which the instance is created.
|
|
||||||
*/
|
|
||||||
public function __construct($entityType);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the internal, static entity cache.
|
* Resets the internal, static entity cache.
|
||||||
*
|
*
|
||||||
@@ -119,6 +111,9 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor: sets basic variables.
|
* Constructor: sets basic variables.
|
||||||
|
*
|
||||||
|
* @param $entityType
|
||||||
|
* The entity type for which the instance is created.
|
||||||
*/
|
*/
|
||||||
public function __construct($entityType) {
|
public function __construct($entityType) {
|
||||||
$this->entityType = $entityType;
|
$this->entityType = $entityType;
|
||||||
@@ -365,9 +360,23 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
|
|||||||
// This ensures the same behavior whether loading from memory or database.
|
// This ensures the same behavior whether loading from memory or database.
|
||||||
if ($conditions) {
|
if ($conditions) {
|
||||||
foreach ($entities as $entity) {
|
foreach ($entities as $entity) {
|
||||||
$entity_values = (array) $entity;
|
// Iterate over all conditions and compare them to the entity
|
||||||
if (array_diff_assoc($conditions, $entity_values)) {
|
// properties. We cannot use array_diff_assoc() here since the
|
||||||
unset($entities[$entity->{$this->idKey}]);
|
// conditions can be nested arrays, too.
|
||||||
|
foreach ($conditions as $property_name => $condition) {
|
||||||
|
if (is_array($condition)) {
|
||||||
|
// Multiple condition values for one property are treated as OR
|
||||||
|
// operation: only if the value is not at all in the condition array
|
||||||
|
// we remove the entity.
|
||||||
|
if (!in_array($entity->{$property_name}, $condition)) {
|
||||||
|
unset($entities[$entity->{$this->idKey}]);
|
||||||
|
continue 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif ($condition != $entity->{$property_name}) {
|
||||||
|
unset($entities[$entity->{$this->idKey}]);
|
||||||
|
continue 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -634,7 +643,7 @@ class EntityFieldQuery {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a condition on field values.
|
* Adds a condition on field values.
|
||||||
*
|
*
|
||||||
* Note that entities with empty field values will be excluded from the
|
* Note that entities with empty field values will be excluded from the
|
||||||
* EntityFieldQuery results when using this method.
|
* EntityFieldQuery results when using this method.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
* Maps PHP error constants to watchdog severity levels.
|
* Maps PHP error constants to watchdog severity levels.
|
||||||
*
|
*
|
||||||
* The error constants are documented at
|
* The error constants are documented at
|
||||||
* http://php.net/manual/en/errorfunc.constants.php
|
* http://php.net/manual/errorfunc.constants.php
|
||||||
*
|
*
|
||||||
* @ingroup logging_severity_levels
|
* @ingroup logging_severity_levels
|
||||||
*/
|
*/
|
||||||
@@ -169,7 +169,7 @@ function error_displayable($error = NULL) {
|
|||||||
* TRUE if the error is fatal.
|
* TRUE if the error is fatal.
|
||||||
*/
|
*/
|
||||||
function _drupal_log_error($error, $fatal = FALSE) {
|
function _drupal_log_error($error, $fatal = FALSE) {
|
||||||
// Initialize a maintenance theme if the boostrap was not complete.
|
// Initialize a maintenance theme if the bootstrap was not complete.
|
||||||
// Do it early because drupal_set_message() triggers a drupal_theme_initialize().
|
// Do it early because drupal_set_message() triggers a drupal_theme_initialize().
|
||||||
if ($fatal && (drupal_get_bootstrap_phase() != DRUPAL_BOOTSTRAP_FULL)) {
|
if ($fatal && (drupal_get_bootstrap_phase() != DRUPAL_BOOTSTRAP_FULL)) {
|
||||||
unset($GLOBALS['theme']);
|
unset($GLOBALS['theme']);
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ define('FILE_STATUS_PERMANENT', 1);
|
|||||||
* wrappers that are appropriate for particular usage. For example, this returns
|
* wrappers that are appropriate for particular usage. For example, this returns
|
||||||
* only stream wrappers that use local file storage:
|
* only stream wrappers that use local file storage:
|
||||||
* @code
|
* @code
|
||||||
* $local_stream_wrappers = file_get_stream_wrappers(STEAM_WRAPPERS_LOCAL);
|
* $local_stream_wrappers = file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL);
|
||||||
* @endcode
|
* @endcode
|
||||||
*
|
*
|
||||||
* The $filter parameter can only filter to types containing a particular flag.
|
* The $filter parameter can only filter to types containing a particular flag.
|
||||||
@@ -99,7 +99,7 @@ define('FILE_STATUS_PERMANENT', 1);
|
|||||||
* array_diff_key() function can be used to help with this. For example, this
|
* array_diff_key() function can be used to help with this. For example, this
|
||||||
* returns only stream wrappers that do not use local file storage:
|
* returns only stream wrappers that do not use local file storage:
|
||||||
* @code
|
* @code
|
||||||
* $remote_stream_wrappers = array_diff_key(file_get_stream_wrappers(STREAM_WRAPPERS_ALL), file_get_stream_wrappers(STEAM_WRAPPERS_LOCAL));
|
* $remote_stream_wrappers = array_diff_key(file_get_stream_wrappers(STREAM_WRAPPERS_ALL), file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL));
|
||||||
* @endcode
|
* @endcode
|
||||||
*
|
*
|
||||||
* @param $filter
|
* @param $filter
|
||||||
@@ -282,10 +282,6 @@ function file_stream_wrapper_uri_normalize($uri) {
|
|||||||
$uri = $scheme . '://' . $target;
|
$uri = $scheme . '://' . $target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// The default scheme is file://
|
|
||||||
$url = 'file://' . $uri;
|
|
||||||
}
|
|
||||||
return $uri;
|
return $uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,8 +470,11 @@ function file_ensure_htaccess() {
|
|||||||
* @param $private
|
* @param $private
|
||||||
* FALSE indicates that $directory should be an open and public directory.
|
* FALSE indicates that $directory should be an open and public directory.
|
||||||
* The default is TRUE which indicates a private and protected directory.
|
* The default is TRUE which indicates a private and protected directory.
|
||||||
|
* @param $force_overwrite
|
||||||
|
* Set to TRUE to attempt to overwrite the existing .htaccess file if one is
|
||||||
|
* already present. Defaults to FALSE.
|
||||||
*/
|
*/
|
||||||
function file_create_htaccess($directory, $private = TRUE) {
|
function file_create_htaccess($directory, $private = TRUE, $force_overwrite = FALSE) {
|
||||||
if (file_uri_scheme($directory)) {
|
if (file_uri_scheme($directory)) {
|
||||||
$directory = file_stream_wrapper_uri_normalize($directory);
|
$directory = file_stream_wrapper_uri_normalize($directory);
|
||||||
}
|
}
|
||||||
@@ -484,19 +483,12 @@ function file_create_htaccess($directory, $private = TRUE) {
|
|||||||
}
|
}
|
||||||
$htaccess_path = $directory . '/.htaccess';
|
$htaccess_path = $directory . '/.htaccess';
|
||||||
|
|
||||||
if (file_exists($htaccess_path)) {
|
if (file_exists($htaccess_path) && !$force_overwrite) {
|
||||||
// Short circuit if the .htaccess file already exists.
|
// Short circuit if the .htaccess file already exists.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($private) {
|
$htaccess_lines = file_htaccess_lines($private);
|
||||||
// Private .htaccess file.
|
|
||||||
$htaccess_lines = "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006\nDeny from all\nOptions None\nOptions +FollowSymLinks";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Public .htaccess file.
|
|
||||||
$htaccess_lines = "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006\nOptions None\nOptions +FollowSymLinks";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the .htaccess file.
|
// Write the .htaccess file.
|
||||||
if (file_put_contents($htaccess_path, $htaccess_lines)) {
|
if (file_put_contents($htaccess_path, $htaccess_lines)) {
|
||||||
@@ -508,6 +500,45 @@ function file_create_htaccess($directory, $private = TRUE) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the standard .htaccess lines that Drupal writes to file directories.
|
||||||
|
*
|
||||||
|
* @param $private
|
||||||
|
* (Optional) Set to FALSE to return the .htaccess lines for an open and
|
||||||
|
* public directory. The default is TRUE, which returns the .htaccess lines
|
||||||
|
* for a private and protected directory.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* A string representing the desired contents of the .htaccess file.
|
||||||
|
*
|
||||||
|
* @see file_create_htaccess()
|
||||||
|
*/
|
||||||
|
function file_htaccess_lines($private = TRUE) {
|
||||||
|
$lines = <<<EOF
|
||||||
|
# Turn off all options we don't need.
|
||||||
|
Options None
|
||||||
|
Options +FollowSymLinks
|
||||||
|
|
||||||
|
# Set the catch-all handler to prevent scripts from being executed.
|
||||||
|
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
|
||||||
|
<Files *>
|
||||||
|
# Override the handler again if we're run later in the evaluation list.
|
||||||
|
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003
|
||||||
|
</Files>
|
||||||
|
|
||||||
|
# If we know how to do it safely, disable the PHP engine entirely.
|
||||||
|
<IfModule mod_php5.c>
|
||||||
|
php_flag engine off
|
||||||
|
</IfModule>
|
||||||
|
EOF;
|
||||||
|
|
||||||
|
if ($private) {
|
||||||
|
$lines = "Deny from all\n\n" . $lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $lines;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads file objects from the database.
|
* Loads file objects from the database.
|
||||||
*
|
*
|
||||||
@@ -590,7 +621,11 @@ function file_save(stdClass $file) {
|
|||||||
module_invoke_all('entity_update', $file, 'file');
|
module_invoke_all('entity_update', $file, 'file');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear internal properties.
|
||||||
unset($file->original);
|
unset($file->original);
|
||||||
|
// Clear the static loading cache.
|
||||||
|
entity_get_controller('file')->resetCache(array($file->fid));
|
||||||
|
|
||||||
return $file;
|
return $file;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -723,10 +758,11 @@ function file_usage_delete(stdClass $file, $module, $type = NULL, $id = NULL, $c
|
|||||||
* stored in the database. This is a powerful function that in many ways
|
* stored in the database. This is a powerful function that in many ways
|
||||||
* performs like an advanced version of copy().
|
* performs like an advanced version of copy().
|
||||||
* - Checks if $source and $destination are valid and readable/writable.
|
* - Checks if $source and $destination are valid and readable/writable.
|
||||||
* - Checks that $source is not equal to $destination; if they are an error
|
|
||||||
* is reported.
|
|
||||||
* - If file already exists in $destination either the call will error out,
|
* - If file already exists in $destination either the call will error out,
|
||||||
* replace the file or rename the file based on the $replace parameter.
|
* replace the file or rename the file based on the $replace parameter.
|
||||||
|
* - If the $source and $destination are equal, the behavior depends on the
|
||||||
|
* $replace parameter. FILE_EXISTS_REPLACE will error out. FILE_EXISTS_RENAME
|
||||||
|
* will rename the file until the $destination is unique.
|
||||||
* - Adds the new file to the files database. If the source file is a
|
* - Adds the new file to the files database. If the source file is a
|
||||||
* temporary file, the resulting file will also be a temporary file. See
|
* temporary file, the resulting file will also be a temporary file. See
|
||||||
* file_save_upload() for details on temporary files.
|
* file_save_upload() for details on temporary files.
|
||||||
@@ -821,10 +857,11 @@ function file_valid_uri($uri) {
|
|||||||
* This is a powerful function that in many ways performs like an advanced
|
* This is a powerful function that in many ways performs like an advanced
|
||||||
* version of copy().
|
* version of copy().
|
||||||
* - Checks if $source and $destination are valid and readable/writable.
|
* - Checks if $source and $destination are valid and readable/writable.
|
||||||
* - Checks that $source is not equal to $destination; if they are an error
|
|
||||||
* is reported.
|
|
||||||
* - If file already exists in $destination either the call will error out,
|
* - If file already exists in $destination either the call will error out,
|
||||||
* replace the file or rename the file based on the $replace parameter.
|
* replace the file or rename the file based on the $replace parameter.
|
||||||
|
* - If the $source and $destination are equal, the behavior depends on the
|
||||||
|
* $replace parameter. FILE_EXISTS_REPLACE will error out. FILE_EXISTS_RENAME
|
||||||
|
* will rename the file until the $destination is unique.
|
||||||
* - Provides a fallback using realpaths if the move fails using stream
|
* - Provides a fallback using realpaths if the move fails using stream
|
||||||
* wrappers. This can occur because PHP's copy() function does not properly
|
* wrappers. This can occur because PHP's copy() function does not properly
|
||||||
* support streams if safe_mode or open_basedir are enabled. See
|
* support streams if safe_mode or open_basedir are enabled. See
|
||||||
@@ -834,9 +871,8 @@ function file_valid_uri($uri) {
|
|||||||
* A string specifying the filepath or URI of the source file.
|
* A string specifying the filepath or URI of the source file.
|
||||||
* @param $destination
|
* @param $destination
|
||||||
* A URI containing the destination that $source should be copied to. The
|
* A URI containing the destination that $source should be copied to. The
|
||||||
* URI may be a bare filepath (without a scheme) and in that case the default
|
* URI may be a bare filepath (without a scheme). If this value is omitted,
|
||||||
* scheme (file://) will be used. If this value is omitted, Drupal's default
|
* Drupal's default files scheme will be used, usually "public://".
|
||||||
* files scheme will be used, usually "public://".
|
|
||||||
* @param $replace
|
* @param $replace
|
||||||
* Replace behavior when the destination file already exists:
|
* Replace behavior when the destination file already exists:
|
||||||
* - FILE_EXISTS_REPLACE - Replace the existing file.
|
* - FILE_EXISTS_REPLACE - Replace the existing file.
|
||||||
@@ -892,7 +928,7 @@ function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXIST
|
|||||||
$destination = file_destination($destination, $replace);
|
$destination = file_destination($destination, $replace);
|
||||||
if ($destination === FALSE) {
|
if ($destination === FALSE) {
|
||||||
drupal_set_message(t('The file %file could not be copied because a file by that name already exists in the destination directory.', array('%file' => $original_source)), 'error');
|
drupal_set_message(t('The file %file could not be copied because a file by that name already exists in the destination directory.', array('%file' => $original_source)), 'error');
|
||||||
watchdog('file', 'File %file could not be copied because a file by that name already exists in the destination directory (%directory)', array('%file' => $original_source, '%destination' => $destination));
|
watchdog('file', 'File %file could not be copied because a file by that name already exists in the destination directory (%directory)', array('%file' => $original_source, '%directory' => $destination));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1113,7 +1149,7 @@ function file_munge_filename($filename, $extensions, $alerts = TRUE) {
|
|||||||
|
|
||||||
// Allow potentially insecure uploads for very savvy users and admin
|
// Allow potentially insecure uploads for very savvy users and admin
|
||||||
if (!variable_get('allow_insecure_uploads', 0)) {
|
if (!variable_get('allow_insecure_uploads', 0)) {
|
||||||
// Remove any null bytes. See http://php.net/manual/en/security.filesystem.nullbytes.php
|
// Remove any null bytes. See http://php.net/manual/security.filesystem.nullbytes.php
|
||||||
$filename = str_replace(chr(0), '', $filename);
|
$filename = str_replace(chr(0), '', $filename);
|
||||||
|
|
||||||
$whitelist = array_unique(explode(' ', trim($extensions)));
|
$whitelist = array_unique(explode(' ', trim($extensions)));
|
||||||
@@ -1261,6 +1297,7 @@ function file_delete(stdClass $file, $force = FALSE) {
|
|||||||
if (file_unmanaged_delete($file->uri)) {
|
if (file_unmanaged_delete($file->uri)) {
|
||||||
db_delete('file_managed')->condition('fid', $file->fid)->execute();
|
db_delete('file_managed')->condition('fid', $file->fid)->execute();
|
||||||
db_delete('file_usage')->condition('fid', $file->fid)->execute();
|
db_delete('file_usage')->condition('fid', $file->fid)->execute();
|
||||||
|
entity_get_controller('file')->resetCache();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -1370,8 +1407,9 @@ function file_space_used($uid = NULL, $status = FILE_STATUS_PERMANENT) {
|
|||||||
* Temporary files are periodically cleaned. To make the file a permanent file,
|
* Temporary files are periodically cleaned. To make the file a permanent file,
|
||||||
* assign the status and use file_save() to save the changes.
|
* assign the status and use file_save() to save the changes.
|
||||||
*
|
*
|
||||||
* @param $source
|
* @param $form_field_name
|
||||||
* A string specifying the filepath or URI of the uploaded file to save.
|
* A string that is the associative array key of the upload form element in
|
||||||
|
* the form array.
|
||||||
* @param $validators
|
* @param $validators
|
||||||
* An optional, associative array of callback functions used to validate the
|
* An optional, associative array of callback functions used to validate the
|
||||||
* file. See file_validate() for a full discussion of the array format.
|
* file. See file_validate() for a full discussion of the array format.
|
||||||
@@ -1382,9 +1420,9 @@ function file_space_used($uid = NULL, $status = FILE_STATUS_PERMANENT) {
|
|||||||
* (Beware: this is not safe and should only be allowed for trusted users, if
|
* (Beware: this is not safe and should only be allowed for trusted users, if
|
||||||
* at all).
|
* at all).
|
||||||
* @param $destination
|
* @param $destination
|
||||||
* A string containing the URI $source should be copied to.
|
* A string containing the URI that the file should be copied to. This must
|
||||||
* This must be a stream wrapper URI. If this value is omitted, Drupal's
|
* be a stream wrapper URI. If this value is omitted, Drupal's temporary
|
||||||
* temporary files scheme will be used ("temporary://").
|
* files scheme will be used ("temporary://").
|
||||||
* @param $replace
|
* @param $replace
|
||||||
* Replace behavior when the destination file already exists:
|
* Replace behavior when the destination file already exists:
|
||||||
* - FILE_EXISTS_REPLACE: Replace the existing file.
|
* - FILE_EXISTS_REPLACE: Replace the existing file.
|
||||||
@@ -1402,45 +1440,45 @@ function file_space_used($uid = NULL, $status = FILE_STATUS_PERMANENT) {
|
|||||||
* - source: Path to the file before it is moved.
|
* - source: Path to the file before it is moved.
|
||||||
* - destination: Path to the file after it is moved (same as 'uri').
|
* - destination: Path to the file after it is moved (same as 'uri').
|
||||||
*/
|
*/
|
||||||
function file_save_upload($source, $validators = array(), $destination = FALSE, $replace = FILE_EXISTS_RENAME) {
|
function file_save_upload($form_field_name, $validators = array(), $destination = FALSE, $replace = FILE_EXISTS_RENAME) {
|
||||||
global $user;
|
global $user;
|
||||||
static $upload_cache;
|
static $upload_cache;
|
||||||
|
|
||||||
// Return cached objects without processing since the file will have
|
// Return cached objects without processing since the file will have
|
||||||
// already been processed and the paths in _FILES will be invalid.
|
// already been processed and the paths in _FILES will be invalid.
|
||||||
if (isset($upload_cache[$source])) {
|
if (isset($upload_cache[$form_field_name])) {
|
||||||
return $upload_cache[$source];
|
return $upload_cache[$form_field_name];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure there's an upload to process.
|
// Make sure there's an upload to process.
|
||||||
if (empty($_FILES['files']['name'][$source])) {
|
if (empty($_FILES['files']['name'][$form_field_name])) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for file upload errors and return FALSE if a lower level system
|
// Check for file upload errors and return FALSE if a lower level system
|
||||||
// error occurred. For a complete list of errors:
|
// error occurred. For a complete list of errors:
|
||||||
// See http://php.net/manual/en/features.file-upload.errors.php.
|
// See http://php.net/manual/features.file-upload.errors.php.
|
||||||
switch ($_FILES['files']['error'][$source]) {
|
switch ($_FILES['files']['error'][$form_field_name]) {
|
||||||
case UPLOAD_ERR_INI_SIZE:
|
case UPLOAD_ERR_INI_SIZE:
|
||||||
case UPLOAD_ERR_FORM_SIZE:
|
case UPLOAD_ERR_FORM_SIZE:
|
||||||
drupal_set_message(t('The file %file could not be saved, because it exceeds %maxsize, the maximum allowed size for uploads.', array('%file' => $_FILES['files']['name'][$source], '%maxsize' => format_size(file_upload_max_size()))), 'error');
|
drupal_set_message(t('The file %file could not be saved, because it exceeds %maxsize, the maximum allowed size for uploads.', array('%file' => $_FILES['files']['name'][$form_field_name], '%maxsize' => format_size(file_upload_max_size()))), 'error');
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
case UPLOAD_ERR_PARTIAL:
|
case UPLOAD_ERR_PARTIAL:
|
||||||
case UPLOAD_ERR_NO_FILE:
|
case UPLOAD_ERR_NO_FILE:
|
||||||
drupal_set_message(t('The file %file could not be saved, because the upload did not complete.', array('%file' => $_FILES['files']['name'][$source])), 'error');
|
drupal_set_message(t('The file %file could not be saved, because the upload did not complete.', array('%file' => $_FILES['files']['name'][$form_field_name])), 'error');
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
case UPLOAD_ERR_OK:
|
case UPLOAD_ERR_OK:
|
||||||
// Final check that this is a valid upload, if it isn't, use the
|
// Final check that this is a valid upload, if it isn't, use the
|
||||||
// default error handler.
|
// default error handler.
|
||||||
if (is_uploaded_file($_FILES['files']['tmp_name'][$source])) {
|
if (is_uploaded_file($_FILES['files']['tmp_name'][$form_field_name])) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unknown error
|
// Unknown error
|
||||||
default:
|
default:
|
||||||
drupal_set_message(t('The file %file could not be saved. An unknown error has occurred.', array('%file' => $_FILES['files']['name'][$source])), 'error');
|
drupal_set_message(t('The file %file could not be saved. An unknown error has occurred.', array('%file' => $_FILES['files']['name'][$form_field_name])), 'error');
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1448,10 +1486,10 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
|
|||||||
$file = new stdClass();
|
$file = new stdClass();
|
||||||
$file->uid = $user->uid;
|
$file->uid = $user->uid;
|
||||||
$file->status = 0;
|
$file->status = 0;
|
||||||
$file->filename = trim(drupal_basename($_FILES['files']['name'][$source]), '.');
|
$file->filename = trim(drupal_basename($_FILES['files']['name'][$form_field_name]), '.');
|
||||||
$file->uri = $_FILES['files']['tmp_name'][$source];
|
$file->uri = $_FILES['files']['tmp_name'][$form_field_name];
|
||||||
$file->filemime = file_get_mimetype($file->filename);
|
$file->filemime = file_get_mimetype($file->filename);
|
||||||
$file->filesize = $_FILES['files']['size'][$source];
|
$file->filesize = $_FILES['files']['size'][$form_field_name];
|
||||||
|
|
||||||
$extensions = '';
|
$extensions = '';
|
||||||
if (isset($validators['file_validate_extensions'])) {
|
if (isset($validators['file_validate_extensions'])) {
|
||||||
@@ -1508,7 +1546,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
$file->source = $source;
|
$file->source = $form_field_name;
|
||||||
// A URI may already have a trailing slash or look like "public://".
|
// A URI may already have a trailing slash or look like "public://".
|
||||||
if (substr($destination, -1) != '/') {
|
if (substr($destination, -1) != '/') {
|
||||||
$destination .= '/';
|
$destination .= '/';
|
||||||
@@ -1517,7 +1555,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
|
|||||||
// If file_destination() returns FALSE then $replace == FILE_EXISTS_ERROR and
|
// If file_destination() returns FALSE then $replace == FILE_EXISTS_ERROR and
|
||||||
// there's an existing file so we need to bail.
|
// there's an existing file so we need to bail.
|
||||||
if ($file->destination === FALSE) {
|
if ($file->destination === FALSE) {
|
||||||
drupal_set_message(t('The file %source could not be uploaded because a file by that name already exists in the destination %directory.', array('%source' => $source, '%directory' => $destination)), 'error');
|
drupal_set_message(t('The file %source could not be uploaded because a file by that name already exists in the destination %directory.', array('%source' => $form_field_name, '%directory' => $destination)), 'error');
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1536,7 +1574,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
|
|||||||
else {
|
else {
|
||||||
$message .= ' ' . array_pop($errors);
|
$message .= ' ' . array_pop($errors);
|
||||||
}
|
}
|
||||||
form_set_error($source, $message);
|
form_set_error($form_field_name, $message);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1544,8 +1582,8 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
|
|||||||
// directory. This overcomes open_basedir restrictions for future file
|
// directory. This overcomes open_basedir restrictions for future file
|
||||||
// operations.
|
// operations.
|
||||||
$file->uri = $file->destination;
|
$file->uri = $file->destination;
|
||||||
if (!drupal_move_uploaded_file($_FILES['files']['tmp_name'][$source], $file->uri)) {
|
if (!drupal_move_uploaded_file($_FILES['files']['tmp_name'][$form_field_name], $file->uri)) {
|
||||||
form_set_error($source, t('File upload error. Could not move uploaded file.'));
|
form_set_error($form_field_name, t('File upload error. Could not move uploaded file.'));
|
||||||
watchdog('file', 'Upload error. Could not move uploaded file %file to destination %destination.', array('%file' => $file->filename, '%destination' => $file->uri));
|
watchdog('file', 'Upload error. Could not move uploaded file %file to destination %destination.', array('%file' => $file->filename, '%destination' => $file->uri));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1565,7 +1603,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
|
|||||||
// If we made it this far it's safe to record this file in the database.
|
// If we made it this far it's safe to record this file in the database.
|
||||||
if ($file = file_save($file)) {
|
if ($file = file_save($file)) {
|
||||||
// Add file to the cache.
|
// Add file to the cache.
|
||||||
$upload_cache[$source] = $file;
|
$upload_cache[$form_field_name] = $file;
|
||||||
return $file;
|
return $file;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -2182,7 +2220,7 @@ function drupal_chmod($uri, $mode = NULL) {
|
|||||||
* @param $uri
|
* @param $uri
|
||||||
* A URI or pathname.
|
* A URI or pathname.
|
||||||
* @param $context
|
* @param $context
|
||||||
* Refer to http://php.net/manual/en/ref.stream.php
|
* Refer to http://php.net/manual/ref.stream.php
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* Boolean TRUE on success, or FALSE on failure.
|
* Boolean TRUE on success, or FALSE on failure.
|
||||||
@@ -2204,29 +2242,21 @@ function drupal_unlink($uri, $context = NULL) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the absolute local filesystem path of a stream URI.
|
* Resolves the absolute filepath of a local URI or filepath.
|
||||||
*
|
*
|
||||||
* This function was originally written to ease the conversion of 6.x code to
|
* The use of drupal_realpath() is discouraged, because it does not work for
|
||||||
* use 7.x stream wrappers. However, it assumes that every URI may be resolved
|
* remote URIs. Except in rare cases, URIs should not be manually resolved.
|
||||||
* to an absolute local filesystem path, and this assumption fails when stream
|
|
||||||
* wrappers are used to support remote file storage. Remote stream wrappers
|
|
||||||
* may implement the realpath method by always returning FALSE. The use of
|
|
||||||
* drupal_realpath() is discouraged, and is slowly being removed from core
|
|
||||||
* functions where possible.
|
|
||||||
*
|
*
|
||||||
* Only use this function if you know that the stream wrapper in the URI uses
|
* Only use this function if you know that the stream wrapper in the URI uses
|
||||||
* the local file system, and you need to pass an absolute path to a function
|
* the local file system, and you need to pass an absolute path to a function
|
||||||
* that is incompatible with stream URIs.
|
* that is incompatible with stream URIs.
|
||||||
*
|
*
|
||||||
* @param $uri
|
* @param string $uri
|
||||||
* A stream wrapper URI or a filesystem path, possibly including one or more
|
* A stream wrapper URI or a filepath, possibly including one or more symbolic
|
||||||
* symbolic links.
|
* links.
|
||||||
*
|
*
|
||||||
* @return
|
* @return string|false
|
||||||
* The absolute local filesystem path (with no symbolic links), or FALSE on
|
* The absolute local filepath (with no symbolic links), or FALSE on failure.
|
||||||
* failure.
|
|
||||||
*
|
|
||||||
* @todo This function is deprecated, and should be removed wherever possible.
|
|
||||||
*
|
*
|
||||||
* @see DrupalStreamWrapperInterface::realpath()
|
* @see DrupalStreamWrapperInterface::realpath()
|
||||||
* @see http://php.net/manual/function.realpath.php
|
* @see http://php.net/manual/function.realpath.php
|
||||||
@@ -2323,7 +2353,7 @@ function drupal_basename($uri, $suffix = NULL) {
|
|||||||
* @param $recursive
|
* @param $recursive
|
||||||
* Default to FALSE.
|
* Default to FALSE.
|
||||||
* @param $context
|
* @param $context
|
||||||
* Refer to http://php.net/manual/en/ref.stream.php
|
* Refer to http://php.net/manual/ref.stream.php
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* Boolean TRUE on success, or FALSE on failure.
|
* Boolean TRUE on success, or FALSE on failure.
|
||||||
@@ -2354,7 +2384,7 @@ function drupal_mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) {
|
|||||||
* @param $uri
|
* @param $uri
|
||||||
* A URI or pathname.
|
* A URI or pathname.
|
||||||
* @param $context
|
* @param $context
|
||||||
* Refer to http://php.net/manual/en/ref.stream.php
|
* Refer to http://php.net/manual/ref.stream.php
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* Boolean TRUE on success, or FALSE on failure.
|
* Boolean TRUE on success, or FALSE on failure.
|
||||||
@@ -2481,20 +2511,10 @@ function file_directory_temp() {
|
|||||||
function file_get_content_headers($file) {
|
function file_get_content_headers($file) {
|
||||||
$name = mime_header_encode($file->filename);
|
$name = mime_header_encode($file->filename);
|
||||||
$type = mime_header_encode($file->filemime);
|
$type = mime_header_encode($file->filemime);
|
||||||
// Serve images, text, and flash content for display rather than download.
|
|
||||||
$inline_types = variable_get('file_inline_types', array('^text/', '^image/', 'flash$'));
|
|
||||||
$disposition = 'attachment';
|
|
||||||
foreach ($inline_types as $inline_type) {
|
|
||||||
// Exclamation marks are used as delimiters to avoid escaping slashes.
|
|
||||||
if (preg_match('!' . $inline_type . '!', $file->filemime)) {
|
|
||||||
$disposition = 'inline';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'Content-Type' => $type,
|
'Content-Type' => $type,
|
||||||
'Content-Length' => $file->filesize,
|
'Content-Length' => $file->filesize,
|
||||||
'Content-Disposition' => $disposition . '; filename="' . $name . '"',
|
|
||||||
'Cache-Control' => 'private',
|
'Cache-Control' => 'private',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -406,10 +406,20 @@ class SkipDotsRecursiveDirectoryIterator extends RecursiveDirectoryIterator {
|
|||||||
*/
|
*/
|
||||||
function __construct($path) {
|
function __construct($path) {
|
||||||
parent::__construct($path);
|
parent::__construct($path);
|
||||||
|
$this->skipdots();
|
||||||
|
}
|
||||||
|
|
||||||
|
function rewind() {
|
||||||
|
parent::rewind();
|
||||||
|
$this->skipdots();
|
||||||
}
|
}
|
||||||
|
|
||||||
function next() {
|
function next() {
|
||||||
parent::next();
|
parent::next();
|
||||||
|
$this->skipdots();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function skipdots() {
|
||||||
while ($this->isDot()) {
|
while ($this->isDot()) {
|
||||||
parent::next();
|
parent::next();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,11 +82,11 @@ class FileTransferFTPExtension extends FileTransferFTP implements FileTransferCh
|
|||||||
if (!$list) {
|
if (!$list) {
|
||||||
$list = array();
|
$list = array();
|
||||||
}
|
}
|
||||||
foreach ($list as $item){
|
foreach ($list as $item) {
|
||||||
if ($item == '.' || $item == '..') {
|
if ($item == '.' || $item == '..') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (@ftp_chdir($this->connection, $item)){
|
if (@ftp_chdir($this->connection, $item)) {
|
||||||
ftp_cdup($this->connection);
|
ftp_cdup($this->connection);
|
||||||
$this->removeDirectory(ftp_pwd($this->connection) . '/' . $item);
|
$this->removeDirectory(ftp_pwd($this->connection) . '/' . $item);
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ class FileTransferFTPExtension extends FileTransferFTP implements FileTransferCh
|
|||||||
|
|
||||||
function chmodJailed($path, $mode, $recursive) {
|
function chmodJailed($path, $mode, $recursive) {
|
||||||
if (!ftp_chmod($this->connection, $mode, $path)) {
|
if (!ftp_chmod($this->connection, $mode, $path)) {
|
||||||
throw new FileTransferException("Unable to set permissions on %file", NULL, array ('%file' => $path));
|
throw new FileTransferException("Unable to set permissions on %file", NULL, array('%file' => $path));
|
||||||
}
|
}
|
||||||
if ($this->isDirectory($path) && $recursive) {
|
if ($this->isDirectory($path) && $recursive) {
|
||||||
$filelist = @ftp_nlist($this->connection, $path);
|
$filelist = @ftp_nlist($this->connection, $path);
|
||||||
|
|||||||
@@ -15,10 +15,9 @@
|
|||||||
* reference the form builder function using \@see. For examples, of this see
|
* reference the form builder function using \@see. For examples, of this see
|
||||||
* system_modules_uninstall() or user_pass(), the latter of which has the
|
* system_modules_uninstall() or user_pass(), the latter of which has the
|
||||||
* following in its doxygen documentation:
|
* following in its doxygen documentation:
|
||||||
*
|
* - \@ingroup forms
|
||||||
* \@ingroup forms
|
* - \@see user_pass_validate()
|
||||||
* \@see user_pass_validate().
|
* - \@see user_pass_submit()
|
||||||
* \@see user_pass_submit().
|
|
||||||
*
|
*
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
@@ -168,6 +167,12 @@ function drupal_get_form($form_id) {
|
|||||||
* processed.
|
* processed.
|
||||||
* - base_form_id: Identification for a base form, as declared in a
|
* - base_form_id: Identification for a base form, as declared in a
|
||||||
* hook_forms() implementation.
|
* hook_forms() implementation.
|
||||||
|
* - immutable: If this flag is set to TRUE, a new form build id is
|
||||||
|
* generated when the form is loaded from the cache. If it is subsequently
|
||||||
|
* saved to the cache again, it will have another cache id and therefore
|
||||||
|
* the original form and form-state will remain unaltered. This is
|
||||||
|
* important when page caching is enabled in order to prevent form state
|
||||||
|
* from leaking between anonymous users.
|
||||||
* - rebuild_info: Internal. Similar to 'build_info', but pertaining to
|
* - rebuild_info: Internal. Similar to 'build_info', but pertaining to
|
||||||
* drupal_rebuild_form().
|
* drupal_rebuild_form().
|
||||||
* - rebuild: Normally, after the entire form processing is completed and
|
* - rebuild: Normally, after the entire form processing is completed and
|
||||||
@@ -235,6 +240,12 @@ function drupal_get_form($form_id) {
|
|||||||
* likely to occur during Ajax operations.
|
* likely to occur during Ajax operations.
|
||||||
* - programmed: If TRUE, the form was submitted programmatically, usually
|
* - programmed: If TRUE, the form was submitted programmatically, usually
|
||||||
* invoked via drupal_form_submit(). Defaults to FALSE.
|
* invoked via drupal_form_submit(). Defaults to FALSE.
|
||||||
|
* - programmed_bypass_access_check: If TRUE, programmatic form submissions
|
||||||
|
* are processed without taking #access into account. Set this to FALSE
|
||||||
|
* when submitting a form programmatically with values that may have been
|
||||||
|
* input by the user executing the current request; this will cause #access
|
||||||
|
* to be respected as it would on a normal form submission. Defaults to
|
||||||
|
* TRUE.
|
||||||
* - process_input: Boolean flag. TRUE signifies correct form submission.
|
* - process_input: Boolean flag. TRUE signifies correct form submission.
|
||||||
* This is always TRUE for programmed forms coming from drupal_form_submit()
|
* This is always TRUE for programmed forms coming from drupal_form_submit()
|
||||||
* (see 'programmed' key), or if the form_id coming from the $_POST data is
|
* (see 'programmed' key), or if the form_id coming from the $_POST data is
|
||||||
@@ -402,6 +413,7 @@ function form_state_defaults() {
|
|||||||
'submitted' => FALSE,
|
'submitted' => FALSE,
|
||||||
'executed' => FALSE,
|
'executed' => FALSE,
|
||||||
'programmed' => FALSE,
|
'programmed' => FALSE,
|
||||||
|
'programmed_bypass_access_check' => TRUE,
|
||||||
'cache'=> FALSE,
|
'cache'=> FALSE,
|
||||||
'method' => 'post',
|
'method' => 'post',
|
||||||
'groups' => array(),
|
'groups' => array(),
|
||||||
@@ -452,17 +464,25 @@ function drupal_rebuild_form($form_id, &$form_state, $old_form = NULL) {
|
|||||||
$form = drupal_retrieve_form($form_id, $form_state);
|
$form = drupal_retrieve_form($form_id, $form_state);
|
||||||
|
|
||||||
// If only parts of the form will be returned to the browser (e.g., Ajax or
|
// If only parts of the form will be returned to the browser (e.g., Ajax or
|
||||||
// RIA clients), re-use the old #build_id to not require client-side code to
|
// RIA clients), or if the form already had a new build ID regenerated when it
|
||||||
// manually update the hidden 'build_id' input element.
|
// was retrieved from the form cache, reuse the existing #build_id.
|
||||||
// Otherwise, a new #build_id is generated, to not clobber the previous
|
// Otherwise, a new #build_id is generated, to not clobber the previous
|
||||||
// build's data in the form cache; also allowing the user to go back to an
|
// build's data in the form cache; also allowing the user to go back to an
|
||||||
// earlier build, make changes, and re-submit.
|
// earlier build, make changes, and re-submit.
|
||||||
// @see drupal_prepare_form()
|
// @see drupal_prepare_form()
|
||||||
if (isset($old_form['#build_id']) && !empty($form_state['rebuild_info']['copy']['#build_id'])) {
|
$enforce_old_build_id = isset($old_form['#build_id']) && !empty($form_state['rebuild_info']['copy']['#build_id']);
|
||||||
|
$old_form_is_mutable_copy = isset($old_form['#build_id_old']);
|
||||||
|
if ($enforce_old_build_id || $old_form_is_mutable_copy) {
|
||||||
$form['#build_id'] = $old_form['#build_id'];
|
$form['#build_id'] = $old_form['#build_id'];
|
||||||
|
if ($old_form_is_mutable_copy) {
|
||||||
|
$form['#build_id_old'] = $old_form['#build_id_old'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$form['#build_id'] = 'form-' . drupal_hash_base64(uniqid(mt_rand(), TRUE) . mt_rand());
|
if (isset($old_form['#build_id'])) {
|
||||||
|
$form['#build_id_old'] = $old_form['#build_id'];
|
||||||
|
}
|
||||||
|
$form['#build_id'] = 'form-' . drupal_random_key();
|
||||||
}
|
}
|
||||||
|
|
||||||
// #action defaults to request_uri(), but in case of Ajax and other partial
|
// #action defaults to request_uri(), but in case of Ajax and other partial
|
||||||
@@ -516,6 +536,15 @@ function form_get_cache($form_build_id, &$form_state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Generate a new #build_id if the cached form was rendered on a cacheable
|
||||||
|
// page.
|
||||||
|
if (!empty($form_state['build_info']['immutable'])) {
|
||||||
|
$form['#build_id_old'] = $form['#build_id'];
|
||||||
|
$form['#build_id'] = 'form-' . drupal_random_key();
|
||||||
|
$form['form_build_id']['#value'] = $form['#build_id'];
|
||||||
|
$form['form_build_id']['#id'] = $form['#build_id'];
|
||||||
|
unset($form_state['build_info']['immutable']);
|
||||||
|
}
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -528,15 +557,28 @@ function form_set_cache($form_build_id, $form, $form_state) {
|
|||||||
// 6 hours cache life time for forms should be plenty.
|
// 6 hours cache life time for forms should be plenty.
|
||||||
$expire = 21600;
|
$expire = 21600;
|
||||||
|
|
||||||
|
// Ensure that the form build_id embedded in the form structure is the same as
|
||||||
|
// the one passed in as a parameter. This is an additional safety measure to
|
||||||
|
// prevent legacy code operating directly with form_get_cache and
|
||||||
|
// form_set_cache from accidentally overwriting immutable form state.
|
||||||
|
if ($form['#build_id'] != $form_build_id) {
|
||||||
|
watchdog('form', 'Form build-id mismatch detected while attempting to store a form in the cache.', array(), WATCHDOG_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Cache form structure.
|
// Cache form structure.
|
||||||
if (isset($form)) {
|
if (isset($form)) {
|
||||||
if ($GLOBALS['user']->uid) {
|
if ($GLOBALS['user']->uid) {
|
||||||
$form['#cache_token'] = drupal_get_token();
|
$form['#cache_token'] = drupal_get_token();
|
||||||
}
|
}
|
||||||
|
unset($form['#build_id_old']);
|
||||||
cache_set('form_' . $form_build_id, $form, 'cache_form', REQUEST_TIME + $expire);
|
cache_set('form_' . $form_build_id, $form, 'cache_form', REQUEST_TIME + $expire);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache form state.
|
// Cache form state.
|
||||||
|
if (variable_get('cache', 0) && drupal_page_is_cacheable()) {
|
||||||
|
$form_state['build_info']['immutable'] = TRUE;
|
||||||
|
}
|
||||||
if ($data = array_diff_key($form_state, array_flip(form_state_keys_no_cache()))) {
|
if ($data = array_diff_key($form_state, array_flip(form_state_keys_no_cache()))) {
|
||||||
cache_set('form_state_' . $form_build_id, $data, 'cache_form', REQUEST_TIME + $expire);
|
cache_set('form_state_' . $form_build_id, $data, 'cache_form', REQUEST_TIME + $expire);
|
||||||
}
|
}
|
||||||
@@ -727,8 +769,9 @@ function drupal_retrieve_form($form_id, &$form_state) {
|
|||||||
// Record the filepath of the include file containing the original form, so
|
// Record the filepath of the include file containing the original form, so
|
||||||
// the form builder callbacks can be loaded when the form is being rebuilt
|
// the form builder callbacks can be loaded when the form is being rebuilt
|
||||||
// from cache on a different path (such as 'system/ajax'). See
|
// from cache on a different path (such as 'system/ajax'). See
|
||||||
// form_get_cache().
|
// form_get_cache(). Don't do this in maintenance mode as Drupal may not be
|
||||||
// $menu_get_item() is not available during installation.
|
// fully bootstrapped (i.e. during installation) in which case
|
||||||
|
// menu_get_item() is not available.
|
||||||
if (!isset($form_state['build_info']['files']['menu']) && !defined('MAINTENANCE_MODE')) {
|
if (!isset($form_state['build_info']['files']['menu']) && !defined('MAINTENANCE_MODE')) {
|
||||||
$item = menu_get_item();
|
$item = menu_get_item();
|
||||||
if (!empty($item['include_file'])) {
|
if (!empty($item['include_file'])) {
|
||||||
@@ -976,7 +1019,7 @@ function drupal_prepare_form($form_id, &$form, &$form_state) {
|
|||||||
// @see drupal_build_form()
|
// @see drupal_build_form()
|
||||||
// @see drupal_rebuild_form()
|
// @see drupal_rebuild_form()
|
||||||
if (!isset($form['#build_id'])) {
|
if (!isset($form['#build_id'])) {
|
||||||
$form['#build_id'] = 'form-' . drupal_hash_base64(uniqid(mt_rand(), TRUE) . mt_rand());
|
$form['#build_id'] = 'form-' . drupal_random_key();
|
||||||
}
|
}
|
||||||
$form['form_build_id'] = array(
|
$form['form_build_id'] = array(
|
||||||
'#type' => 'hidden',
|
'#type' => 'hidden',
|
||||||
@@ -1128,6 +1171,12 @@ function drupal_validate_form($form_id, &$form, &$form_state) {
|
|||||||
|
|
||||||
// Setting this error will cause the form to fail validation.
|
// Setting this error will cause the form to fail validation.
|
||||||
form_set_error('form_token', t('The form has become outdated. Copy any unsaved work in the form below and then <a href="@link">reload this page</a>.', array('@link' => $url)));
|
form_set_error('form_token', t('The form has become outdated. Copy any unsaved work in the form below and then <a href="@link">reload this page</a>.', array('@link' => $url)));
|
||||||
|
|
||||||
|
// Stop here and don't run any further validation handlers, because they
|
||||||
|
// could invoke non-safe operations which opens the door for CSRF
|
||||||
|
// vulnerabilities.
|
||||||
|
$validated_forms[$form_id] = TRUE;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1978,7 +2027,7 @@ function _form_builder_handle_input_element($form_id, &$element, &$form_state) {
|
|||||||
// #access=FALSE on an element usually allow access for some users, so forms
|
// #access=FALSE on an element usually allow access for some users, so forms
|
||||||
// submitted with drupal_form_submit() may bypass access restriction and be
|
// submitted with drupal_form_submit() may bypass access restriction and be
|
||||||
// treated as high-privilege users instead.
|
// treated as high-privilege users instead.
|
||||||
$process_input = empty($element['#disabled']) && ($form_state['programmed'] || ($form_state['process_input'] && (!isset($element['#access']) || $element['#access'])));
|
$process_input = empty($element['#disabled']) && (($form_state['programmed'] && $form_state['programmed_bypass_access_check']) || ($form_state['process_input'] && (!isset($element['#access']) || $element['#access'])));
|
||||||
|
|
||||||
// Set the element's #value property.
|
// Set the element's #value property.
|
||||||
if (!isset($element['#value']) && !array_key_exists('#value', $element)) {
|
if (!isset($element['#value']) && !array_key_exists('#value', $element)) {
|
||||||
@@ -3051,14 +3100,12 @@ function form_process_radios($element) {
|
|||||||
* @param $variables
|
* @param $variables
|
||||||
* An associative array containing:
|
* An associative array containing:
|
||||||
* - element: An associative array containing the properties of the element.
|
* - element: An associative array containing the properties of the element.
|
||||||
* Properties used: #title, #value, #return_value, #description, #required,
|
* Properties used: #id, #name, #attributes, #checked, #return_value.
|
||||||
* #attributes, #checked.
|
|
||||||
*
|
*
|
||||||
* @ingroup themeable
|
* @ingroup themeable
|
||||||
*/
|
*/
|
||||||
function theme_checkbox($variables) {
|
function theme_checkbox($variables) {
|
||||||
$element = $variables['element'];
|
$element = $variables['element'];
|
||||||
$t = get_t();
|
|
||||||
$element['#attributes']['type'] = 'checkbox';
|
$element['#attributes']['type'] = 'checkbox';
|
||||||
element_set_attributes($element, array('id', 'name', '#return_value' => 'value'));
|
element_set_attributes($element, array('id', 'name', '#return_value' => 'value'));
|
||||||
|
|
||||||
@@ -3662,35 +3709,6 @@ function form_pre_render_fieldset($element) {
|
|||||||
/**
|
/**
|
||||||
* Creates a group formatted as vertical tabs.
|
* Creates a group formatted as vertical tabs.
|
||||||
*
|
*
|
||||||
* Note that autocomplete callbacks should include special handling as the
|
|
||||||
* user's input may contain forward slashes. If the user-submitted string has a
|
|
||||||
* '/' in the text that is sent in the autocomplete request, the menu system
|
|
||||||
* will split the text and pass it to the callback as multiple arguments.
|
|
||||||
*
|
|
||||||
* Suppose your autocomplete path in the menu system is 'mymodule_autocomplete.'
|
|
||||||
* In your form you have:
|
|
||||||
* @code
|
|
||||||
* '#autocomplete_path' => 'mymodule_autocomplete/' . $some_key . '/' . $some_id,
|
|
||||||
* @endcode
|
|
||||||
* The user types in "keywords" so the full path called is:
|
|
||||||
* 'mymodule_autocomplete/$some_key/$some_id/keywords'
|
|
||||||
*
|
|
||||||
* You should include code similar to the following to handle slashes in the
|
|
||||||
* input:
|
|
||||||
* @code
|
|
||||||
* function mymodule_autocomplete_callback($arg1, $arg2, $keywords) {
|
|
||||||
* $args = func_get_args();
|
|
||||||
* // We need to remove $arg1 and $arg2 from the beginning of the array so we
|
|
||||||
* // are left with the keywords.
|
|
||||||
* array_shift($args);
|
|
||||||
* array_shift($args);
|
|
||||||
* // We store the user's original input in $keywords, including any slashes.
|
|
||||||
* $keywords = implode('/', $args);
|
|
||||||
*
|
|
||||||
* // Your code here.
|
|
||||||
* }
|
|
||||||
* @endcode
|
|
||||||
*
|
|
||||||
* @param $element
|
* @param $element
|
||||||
* An associative array containing the properties and children of the
|
* An associative array containing the properties and children of the
|
||||||
* fieldset.
|
* fieldset.
|
||||||
@@ -4039,8 +4057,6 @@ function theme_file($variables) {
|
|||||||
*/
|
*/
|
||||||
function theme_form_element($variables) {
|
function theme_form_element($variables) {
|
||||||
$element = &$variables['element'];
|
$element = &$variables['element'];
|
||||||
// This is also used in the installer, pre-database setup.
|
|
||||||
$t = get_t();
|
|
||||||
|
|
||||||
// This function is invoked as theme wrapper, but the rendered form element
|
// This function is invoked as theme wrapper, but the rendered form element
|
||||||
// may not necessarily have been processed by form_builder().
|
// may not necessarily have been processed by form_builder().
|
||||||
@@ -4199,7 +4215,7 @@ function _form_set_class(&$element, $class = array()) {
|
|||||||
if (!empty($element['#required'])) {
|
if (!empty($element['#required'])) {
|
||||||
$element['#attributes']['class'][] = 'required';
|
$element['#attributes']['class'][] = 'required';
|
||||||
}
|
}
|
||||||
if (isset($element['#parents']) && form_get_error($element) !== NULL) {
|
if (isset($element['#parents']) && form_get_error($element) !== NULL && !empty($element['#validated'])) {
|
||||||
$element['#attributes']['class'][] = 'error';
|
$element['#attributes']['class'][] = 'error';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4276,7 +4292,7 @@ function element_validate_number($element, &$form_state) {
|
|||||||
* returns any user input in the 'results' or 'message' keys of $context,
|
* returns any user input in the 'results' or 'message' keys of $context,
|
||||||
* it must also sanitize them first.
|
* it must also sanitize them first.
|
||||||
*
|
*
|
||||||
* Sample batch operations:
|
* Sample callback_batch_operation():
|
||||||
* @code
|
* @code
|
||||||
* // Simple and artificial: load a node of a given type for a given user
|
* // Simple and artificial: load a node of a given type for a given user
|
||||||
* function my_function_1($uid, $type, &$context) {
|
* function my_function_1($uid, $type, &$context) {
|
||||||
@@ -4328,7 +4344,7 @@ function element_validate_number($element, &$form_state) {
|
|||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*
|
*
|
||||||
* Sample 'finished' callback:
|
* Sample callback_batch_finished():
|
||||||
* @code
|
* @code
|
||||||
* function batch_test_finished($success, $results, $operations) {
|
* function batch_test_finished($success, $results, $operations) {
|
||||||
* // The 'success' parameter means no fatal PHP errors were detected. All
|
* // The 'success' parameter means no fatal PHP errors were detected. All
|
||||||
@@ -4367,12 +4383,14 @@ function element_validate_number($element, &$form_state) {
|
|||||||
* @param $batch_definition
|
* @param $batch_definition
|
||||||
* An associative array defining the batch, with the following elements (all
|
* An associative array defining the batch, with the following elements (all
|
||||||
* are optional except as noted):
|
* are optional except as noted):
|
||||||
* - operations: (required) Array of function calls to be performed.
|
* - operations: (required) Array of operations to be performed, where each
|
||||||
|
* item is an array consisting of the name of an implementation of
|
||||||
|
* callback_batch_operation() and an array of parameter.
|
||||||
* Example:
|
* Example:
|
||||||
* @code
|
* @code
|
||||||
* array(
|
* array(
|
||||||
* array('my_function_1', array($arg1)),
|
* array('callback_batch_operation_1', array($arg1)),
|
||||||
* array('my_function_2', array($arg2_1, $arg2_2)),
|
* array('callback_batch_operation_2', array($arg2_1, $arg2_2)),
|
||||||
* )
|
* )
|
||||||
* @endcode
|
* @endcode
|
||||||
* - title: A safe, translated string to use as the title for the progress
|
* - title: A safe, translated string to use as the title for the progress
|
||||||
@@ -4384,10 +4402,10 @@ function element_validate_number($element, &$form_state) {
|
|||||||
* @elapsed. Defaults to t('Completed @current of @total.').
|
* @elapsed. Defaults to t('Completed @current of @total.').
|
||||||
* - error_message: Message displayed if an error occurred while processing
|
* - error_message: Message displayed if an error occurred while processing
|
||||||
* the batch. Defaults to t('An error has occurred.').
|
* the batch. Defaults to t('An error has occurred.').
|
||||||
* - finished: Name of a function to be executed after the batch has
|
* - finished: Name of an implementation of callback_batch_finished(). This is
|
||||||
* completed. This should be used to perform any result massaging that may
|
* executed after the batch has completed. This should be used to perform
|
||||||
* be needed, and possibly save data in $_SESSION for display after final
|
* any result massaging that may be needed, and possibly save data in
|
||||||
* page redirection.
|
* $_SESSION for display after final page redirection.
|
||||||
* - file: Path to the file containing the definitions of the 'operations' and
|
* - file: Path to the file containing the definitions of the 'operations' and
|
||||||
* 'finished' functions, for instance if they don't reside in the main
|
* 'finished' functions, for instance if they don't reside in the main
|
||||||
* .module file. The path should be relative to base_path(), and thus should
|
* .module file. The path should be relative to base_path(), and thus should
|
||||||
|
|||||||
@@ -233,11 +233,11 @@ function image_dimensions_scale(array &$dimensions, $width = NULL, $height = NUL
|
|||||||
* @param $image
|
* @param $image
|
||||||
* An image object returned by image_load().
|
* An image object returned by image_load().
|
||||||
* @param $width
|
* @param $width
|
||||||
* The target width, in pixels. This value is omitted then the scaling will
|
* The target width, in pixels. If this value is NULL then the scaling will
|
||||||
* based only on the height value.
|
* be based only on the height value.
|
||||||
* @param $height
|
* @param $height
|
||||||
* The target height, in pixels. This value is omitted then the scaling will
|
* The target height, in pixels. If this value is NULL then the scaling will
|
||||||
* based only on the width value.
|
* be based only on the width value.
|
||||||
* @param $upscale
|
* @param $upscale
|
||||||
* Boolean indicating that files smaller than the dimensions will be scaled
|
* Boolean indicating that files smaller than the dimensions will be scaled
|
||||||
* up. This generally results in a low quality image.
|
* up. This generally results in a low quality image.
|
||||||
|
|||||||
@@ -692,6 +692,21 @@ function install_full_redirect_url($install_state) {
|
|||||||
*/
|
*/
|
||||||
function install_display_output($output, $install_state) {
|
function install_display_output($output, $install_state) {
|
||||||
drupal_page_header();
|
drupal_page_header();
|
||||||
|
|
||||||
|
// Prevent install.php from being indexed when installed in a sub folder.
|
||||||
|
// robots.txt rules are not read if the site is within domain.com/subfolder
|
||||||
|
// resulting in /subfolder/install.php being found through search engines.
|
||||||
|
// When settings.php is writeable this can be used via an external database
|
||||||
|
// leading a malicious user to gain php access to the server.
|
||||||
|
$noindex_meta_tag = array(
|
||||||
|
'#tag' => 'meta',
|
||||||
|
'#attributes' => array(
|
||||||
|
'name' => 'robots',
|
||||||
|
'content' => 'noindex, nofollow',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
drupal_add_html_head($noindex_meta_tag, 'install_meta_robots');
|
||||||
|
|
||||||
// Only show the task list if there is an active task; otherwise, the page
|
// Only show the task list if there is an active task; otherwise, the page
|
||||||
// request has ended before tasks have even been started, so there is nothing
|
// request has ended before tasks have even been started, so there is nothing
|
||||||
// meaningful to show.
|
// meaningful to show.
|
||||||
@@ -766,6 +781,15 @@ function install_system_module(&$install_state) {
|
|||||||
// Install system.module.
|
// Install system.module.
|
||||||
drupal_install_system();
|
drupal_install_system();
|
||||||
|
|
||||||
|
// Call file_ensure_htaccess() to ensure that all of Drupal's standard
|
||||||
|
// directories (e.g., the public and private files directories) have
|
||||||
|
// appropriate .htaccess files. These directories will have already been
|
||||||
|
// created by this point in the installer, since Drupal creates them during
|
||||||
|
// the install_verify_requirements() task. Note that we cannot call
|
||||||
|
// file_ensure_htaccess() any earlier than this, since it relies on
|
||||||
|
// system.module in order to work.
|
||||||
|
file_ensure_htaccess();
|
||||||
|
|
||||||
// Enable the user module so that sessions can be recorded during the
|
// Enable the user module so that sessions can be recorded during the
|
||||||
// upcoming bootstrap step.
|
// upcoming bootstrap step.
|
||||||
module_enable(array('user'), FALSE);
|
module_enable(array('user'), FALSE);
|
||||||
@@ -981,7 +1005,7 @@ function install_settings_form_submit($form, &$form_state) {
|
|||||||
'required' => TRUE,
|
'required' => TRUE,
|
||||||
);
|
);
|
||||||
$settings['drupal_hash_salt'] = array(
|
$settings['drupal_hash_salt'] = array(
|
||||||
'value' => drupal_hash_base64(drupal_random_bytes(55)),
|
'value' => drupal_random_key(),
|
||||||
'required' => TRUE,
|
'required' => TRUE,
|
||||||
);
|
);
|
||||||
drupal_rewrite_settings($settings);
|
drupal_rewrite_settings($settings);
|
||||||
@@ -1041,7 +1065,21 @@ function install_select_profile(&$install_state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects an installation profile from a list or from a $_POST submission.
|
* Selects an installation profile.
|
||||||
|
*
|
||||||
|
* A profile will be selected if:
|
||||||
|
* - Only one profile is available,
|
||||||
|
* - A profile was submitted through $_POST,
|
||||||
|
* - Exactly one of the profiles is marked as "exclusive".
|
||||||
|
* If multiple profiles are marked as "exclusive" then no profile will be
|
||||||
|
* selected.
|
||||||
|
*
|
||||||
|
* @param array $profiles
|
||||||
|
* An associative array of profiles with the machine-readable names as keys.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The machine-readable name of the selected profile or NULL if no profile was
|
||||||
|
* selected.
|
||||||
*/
|
*/
|
||||||
function _install_select_profile($profiles) {
|
function _install_select_profile($profiles) {
|
||||||
if (sizeof($profiles) == 0) {
|
if (sizeof($profiles) == 0) {
|
||||||
@@ -1061,6 +1099,23 @@ function _install_select_profile($profiles) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Check for a profile marked as "exclusive" and ensure that only one
|
||||||
|
// profile is marked as such.
|
||||||
|
$exclusive_profile = NULL;
|
||||||
|
foreach ($profiles as $profile) {
|
||||||
|
$profile_info = install_profile_info($profile->name);
|
||||||
|
if (!empty($profile_info['exclusive'])) {
|
||||||
|
if (empty($exclusive_profile)) {
|
||||||
|
$exclusive_profile = $profile->name;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// We found a second "exclusive" profile. There's no way to choose
|
||||||
|
// between them, so we ignore the property.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $exclusive_profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -741,20 +741,27 @@ function drupal_install_system() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uninstalls a given list of modules.
|
* Uninstalls a given list of disabled modules.
|
||||||
*
|
*
|
||||||
* @param $module_list
|
* @param array $module_list
|
||||||
* The modules to uninstall.
|
* The modules to uninstall. It is the caller's responsibility to ensure that
|
||||||
* @param $uninstall_dependents
|
* all modules in this list have already been disabled before this function
|
||||||
* If TRUE, the function will check that all modules which depend on the
|
* is called.
|
||||||
* passed-in module list either are already uninstalled or contained in the
|
* @param bool $uninstall_dependents
|
||||||
* list, and it will ensure that the modules are uninstalled in the correct
|
* (optional) If TRUE, the function will check that all modules which depend
|
||||||
* order. This incurs a significant performance cost, so use FALSE if you
|
* on the passed-in module list either are already uninstalled or contained in
|
||||||
* know $module_list is already complete and in the correct order.
|
* the list, and it will ensure that the modules are uninstalled in the
|
||||||
|
* correct order. This incurs a significant performance cost, so use FALSE if
|
||||||
|
* you know $module_list is already complete and in the correct order.
|
||||||
|
* Defaults to TRUE.
|
||||||
*
|
*
|
||||||
* @return
|
* @return bool
|
||||||
* FALSE if one or more dependent modules are missing from the list, TRUE
|
* Returns TRUE if the operation succeeds or FALSE if it aborts due to an
|
||||||
* otherwise.
|
* unsafe condition, namely, $uninstall_dependents is TRUE and a module in
|
||||||
|
* $module_list has dependents which are not already uninstalled and not also
|
||||||
|
* included in $module_list).
|
||||||
|
*
|
||||||
|
* @see module_disable()
|
||||||
*/
|
*/
|
||||||
function drupal_uninstall_modules($module_list = array(), $uninstall_dependents = TRUE) {
|
function drupal_uninstall_modules($module_list = array(), $uninstall_dependents = TRUE) {
|
||||||
if ($uninstall_dependents) {
|
if ($uninstall_dependents) {
|
||||||
@@ -766,7 +773,7 @@ function drupal_uninstall_modules($module_list = array(), $uninstall_dependents
|
|||||||
$profile = drupal_get_profile();
|
$profile = drupal_get_profile();
|
||||||
while (list($module) = each($module_list)) {
|
while (list($module) = each($module_list)) {
|
||||||
if (!isset($module_data[$module]) || drupal_get_installed_schema_version($module) == SCHEMA_UNINSTALLED) {
|
if (!isset($module_data[$module]) || drupal_get_installed_schema_version($module) == SCHEMA_UNINSTALLED) {
|
||||||
// This module doesn't exist or is already uninstalled, skip it.
|
// This module doesn't exist or is already uninstalled. Skip it.
|
||||||
unset($module_list[$module]);
|
unset($module_list[$module]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -799,7 +806,7 @@ function drupal_uninstall_modules($module_list = array(), $uninstall_dependents
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($module_list)) {
|
if (!empty($module_list)) {
|
||||||
// Call hook_module_uninstall to let other modules act
|
// Let other modules react.
|
||||||
module_invoke_all('modules_uninstalled', $module_list);
|
module_invoke_all('modules_uninstalled', $module_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1127,7 +1134,6 @@ function st($string, array $args = array(), array $options = array()) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once DRUPAL_ROOT . '/includes/theme.inc';
|
|
||||||
// Transform arguments before inserting them
|
// Transform arguments before inserting them
|
||||||
foreach ($args as $key => $value) {
|
foreach ($args as $key => $value) {
|
||||||
switch ($key[0]) {
|
switch ($key[0]) {
|
||||||
@@ -1244,6 +1250,12 @@ function drupal_check_module($module) {
|
|||||||
* - distribution_name: The name of the Drupal distribution that is being
|
* - distribution_name: The name of the Drupal distribution that is being
|
||||||
* installed, to be shown throughout the installation process. Defaults to
|
* installed, to be shown throughout the installation process. Defaults to
|
||||||
* 'Drupal'.
|
* 'Drupal'.
|
||||||
|
* - exclusive: If the install profile is intended to be the only eligible
|
||||||
|
* choice in a distribution, setting exclusive = TRUE will auto-select it
|
||||||
|
* during installation, and the install profile selection screen will be
|
||||||
|
* skipped. If more than one profile is found where exclusive = TRUE then
|
||||||
|
* this property will have no effect and the profile selection screen will
|
||||||
|
* be shown as normal with all available profiles shown.
|
||||||
*
|
*
|
||||||
* Note that this function does an expensive file system scan to get info file
|
* Note that this function does an expensive file system scan to get info file
|
||||||
* information for dependencies. If you only need information from the info
|
* information for dependencies. If you only need information from the info
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ function _country_get_predefined_list() {
|
|||||||
'BM' => $t('Bermuda'),
|
'BM' => $t('Bermuda'),
|
||||||
'BN' => $t('Brunei'),
|
'BN' => $t('Brunei'),
|
||||||
'BO' => $t('Bolivia'),
|
'BO' => $t('Bolivia'),
|
||||||
|
'BQ' => $t('Caribbean Netherlands'),
|
||||||
'BR' => $t('Brazil'),
|
'BR' => $t('Brazil'),
|
||||||
'BS' => $t('Bahamas'),
|
'BS' => $t('Bahamas'),
|
||||||
'BT' => $t('Bhutan'),
|
'BT' => $t('Bhutan'),
|
||||||
@@ -74,8 +75,8 @@ function _country_get_predefined_list() {
|
|||||||
'CO' => $t('Colombia'),
|
'CO' => $t('Colombia'),
|
||||||
'CR' => $t('Costa Rica'),
|
'CR' => $t('Costa Rica'),
|
||||||
'CU' => $t('Cuba'),
|
'CU' => $t('Cuba'),
|
||||||
'CW' => $t('Curaçao'),
|
|
||||||
'CV' => $t('Cape Verde'),
|
'CV' => $t('Cape Verde'),
|
||||||
|
'CW' => $t('Curaçao'),
|
||||||
'CX' => $t('Christmas Island'),
|
'CX' => $t('Christmas Island'),
|
||||||
'CY' => $t('Cyprus'),
|
'CY' => $t('Cyprus'),
|
||||||
'CZ' => $t('Czech Republic'),
|
'CZ' => $t('Czech Republic'),
|
||||||
@@ -230,8 +231,10 @@ function _country_get_predefined_list() {
|
|||||||
'SN' => $t('Senegal'),
|
'SN' => $t('Senegal'),
|
||||||
'SO' => $t('Somalia'),
|
'SO' => $t('Somalia'),
|
||||||
'SR' => $t('Suriname'),
|
'SR' => $t('Suriname'),
|
||||||
|
'SS' => $t('South Sudan'),
|
||||||
'ST' => $t('Sao Tome and Principe'),
|
'ST' => $t('Sao Tome and Principe'),
|
||||||
'SV' => $t('El Salvador'),
|
'SV' => $t('El Salvador'),
|
||||||
|
'SX' => $t('Sint Maarten'),
|
||||||
'SY' => $t('Syria'),
|
'SY' => $t('Syria'),
|
||||||
'SZ' => $t('Swaziland'),
|
'SZ' => $t('Swaziland'),
|
||||||
'TC' => $t('Turks and Caicos Islands'),
|
'TC' => $t('Turks and Caicos Islands'),
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* Multiple language handling functionality.
|
* Language Negotiation API.
|
||||||
|
*
|
||||||
|
* @see http://drupal.org/node/1497272
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,7 +13,95 @@
|
|||||||
define('LANGUAGE_NEGOTIATION_DEFAULT', 'language-default');
|
define('LANGUAGE_NEGOTIATION_DEFAULT', 'language-default');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all the defined language types.
|
* @defgroup language_negotiation Language Negotiation API functionality
|
||||||
|
* @{
|
||||||
|
* Functions to customize the language types and the negotiation process.
|
||||||
|
*
|
||||||
|
* The language negotiation API is based on two major concepts:
|
||||||
|
* - Language types: types of translatable data (the types of data that a user
|
||||||
|
* can view or request).
|
||||||
|
* - Language negotiation providers: functions for determining which language to
|
||||||
|
* use to present a particular piece of data to the user.
|
||||||
|
* Both language types and language negotiation providers are customizable.
|
||||||
|
*
|
||||||
|
* Drupal defines three built-in language types:
|
||||||
|
* - Interface language: The page's main language, used to present translated
|
||||||
|
* user interface elements such as titles, labels, help text, and messages.
|
||||||
|
* - Content language: The language used to present content that is available
|
||||||
|
* in more than one language (see
|
||||||
|
* @link field_language Field Language API @endlink for details).
|
||||||
|
* - URL language: The language associated with URLs. When generating a URL,
|
||||||
|
* this value will be used by url() as a default if no explicit preference is
|
||||||
|
* provided.
|
||||||
|
* Modules can define additional language types through
|
||||||
|
* hook_language_types_info(), and alter existing language type definitions
|
||||||
|
* through hook_language_types_info_alter().
|
||||||
|
*
|
||||||
|
* Language types may be configurable or fixed. The language negotiation
|
||||||
|
* providers associated with a configurable language type can be explicitly
|
||||||
|
* set through the user interface. A fixed language type has predetermined
|
||||||
|
* (module-defined) language negotiation settings and, thus, does not appear in
|
||||||
|
* the configuration page. Here is a code snippet that makes the content
|
||||||
|
* language (which by default inherits the interface language's values)
|
||||||
|
* configurable:
|
||||||
|
* @code
|
||||||
|
* function mymodule_language_types_info_alter(&$language_types) {
|
||||||
|
* unset($language_types[LANGUAGE_TYPE_CONTENT]['fixed']);
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* Every language type can have a different set of language negotiation
|
||||||
|
* providers assigned to it. Different language types often share the same
|
||||||
|
* language negotiation settings, but they can have independent settings if
|
||||||
|
* needed. If two language types are configured the same way, their language
|
||||||
|
* switcher configuration will be functionally identical and the same settings
|
||||||
|
* will act on both language types.
|
||||||
|
*
|
||||||
|
* Drupal defines the following built-in language negotiation providers:
|
||||||
|
* - URL: Determine the language from the URL (path prefix or domain).
|
||||||
|
* - Session: Determine the language from a request/session parameter.
|
||||||
|
* - User: Follow the user's language preference.
|
||||||
|
* - Browser: Determine the language from the browser's language settings.
|
||||||
|
* - Default language: Use the default site language.
|
||||||
|
* Language negotiation providers are simple callback functions that implement a
|
||||||
|
* particular logic to return a language code. For instance, the URL provider
|
||||||
|
* searches for a valid path prefix or domain name in the current request URL.
|
||||||
|
* If a language negotiation provider does not return a valid language code, the
|
||||||
|
* next provider associated to the language type (based on provider weight) is
|
||||||
|
* invoked.
|
||||||
|
*
|
||||||
|
* Modules can define additional language negotiation providers through
|
||||||
|
* hook_language_negotiation_info(), and alter existing providers through
|
||||||
|
* hook_language_negotiation_info_alter(). Here is an example snippet that lets
|
||||||
|
* path prefixes be ignored for administrative paths:
|
||||||
|
* @code
|
||||||
|
* function mymodule_language_negotiation_info_alter(&$negotiation_info) {
|
||||||
|
* // Replace the core function with our own function.
|
||||||
|
* module_load_include('language', 'inc', 'language.negotiation');
|
||||||
|
* $negotiation_info[LANGUAGE_NEGOTIATION_URL]['callbacks']['language'] = 'mymodule_from_url';
|
||||||
|
* $negotiation_info[LANGUAGE_NEGOTIATION_URL]['file'] = drupal_get_path('module', 'mymodule') . '/mymodule.module';
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* function mymodule_from_url($languages) {
|
||||||
|
* // Use the core URL language negotiation provider to get a valid language
|
||||||
|
* // code.
|
||||||
|
* module_load_include('language', 'inc', 'language.negotiation');
|
||||||
|
* $langcode = language_from_url($languages);
|
||||||
|
*
|
||||||
|
* // If we are on an administrative path, override with the default language.
|
||||||
|
* if (isset($_GET['q']) && strtok($_GET['q'], '/') == 'admin') {
|
||||||
|
* return language_default()->langcode;
|
||||||
|
* }
|
||||||
|
* return $langcode;
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* For more information, see
|
||||||
|
* @link http://drupal.org/node/1497272 Language Negotiation API @endlink
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the defined language types.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* An array of language type names. The name will be used as the global
|
* An array of language type names. The name will be used as the global
|
||||||
@@ -30,11 +120,11 @@ function language_types_info() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return only the configurable language types.
|
* Returns only the configurable language types.
|
||||||
*
|
*
|
||||||
* A language type maybe configurable or fixed. A fixed language type is a type
|
* A language type maybe configurable or fixed. A fixed language type is a type
|
||||||
* whose negotiation values are unchangeable and defined while defining the
|
* whose language negotiation providers are module-defined and not altered
|
||||||
* language type itself.
|
* through the user interface.
|
||||||
*
|
*
|
||||||
* @param $stored
|
* @param $stored
|
||||||
* Optional. By default retrieves values from the 'language_types' variable to
|
* Optional. By default retrieves values from the 'language_types' variable to
|
||||||
@@ -68,7 +158,7 @@ function language_types_configurable($stored = TRUE) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable the given language types.
|
* Disables the given language types.
|
||||||
*
|
*
|
||||||
* @param $types
|
* @param $types
|
||||||
* An array of language types.
|
* An array of language types.
|
||||||
@@ -122,16 +212,17 @@ function language_types_set() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a language provider is enabled.
|
* Checks whether a language negotiation provider is enabled for a language type.
|
||||||
*
|
*
|
||||||
* This has two possible behaviors:
|
* This has two possible behaviors:
|
||||||
* - If $provider_id is given return its ID if enabled, FALSE otherwise.
|
* - If $provider_id is given return its ID if enabled, FALSE otherwise.
|
||||||
* - If no ID is passed the first enabled language provider is returned.
|
* - If no ID is passed the first enabled language negotiation provider is
|
||||||
|
* returned.
|
||||||
*
|
*
|
||||||
* @param $type
|
* @param $type
|
||||||
* The language negotiation type.
|
* The language negotiation provider type.
|
||||||
* @param $provider_id
|
* @param $provider_id
|
||||||
* The language provider ID.
|
* The language negotiation provider ID.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* The provider ID if it is enabled, FALSE otherwise.
|
* The provider ID if it is enabled, FALSE otherwise.
|
||||||
@@ -155,14 +246,13 @@ function language_negotiation_get($type, $provider_id = NULL) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the given language provider is enabled for any configurable language
|
* Checks if the language negotiation provider is enabled for any language type.
|
||||||
* type.
|
|
||||||
*
|
*
|
||||||
* @param $provider_id
|
* @param $provider_id
|
||||||
* The language provider ID.
|
* The language negotiation provider ID.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* TRUE if there is at least one language type for which the give language
|
* TRUE if there is at least one language type for which the given language
|
||||||
* provider is enabled, FALSE otherwise.
|
* provider is enabled, FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
function language_negotiation_get_any($provider_id) {
|
function language_negotiation_get_any($provider_id) {
|
||||||
@@ -176,7 +266,7 @@ function language_negotiation_get_any($provider_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the language switch links for the given language.
|
* Returns the language switch links for the given language.
|
||||||
*
|
*
|
||||||
* @param $type
|
* @param $type
|
||||||
* The language negotiation type.
|
* The language negotiation type.
|
||||||
@@ -223,7 +313,7 @@ function language_negotiation_get_switch_links($type, $path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates language configuration to remove any language provider that is no longer defined.
|
* Removes any unused language negotiation providers from the configuration.
|
||||||
*/
|
*/
|
||||||
function language_negotiation_purge() {
|
function language_negotiation_purge() {
|
||||||
// Ensure that we are getting the defined language negotiation information. An
|
// Ensure that we are getting the defined language negotiation information. An
|
||||||
@@ -246,12 +336,12 @@ function language_negotiation_purge() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save a list of language providers.
|
* Saves a list of language negotiation providers.
|
||||||
*
|
*
|
||||||
* @param $type
|
* @param $type
|
||||||
* The language negotiation type.
|
* The language negotiation type.
|
||||||
* @param $language_providers
|
* @param $language_providers
|
||||||
* An array of language provider weights keyed by id.
|
* An array of language negotiation provider weights keyed by provider ID.
|
||||||
* @see language_provider_weight()
|
* @see language_provider_weight()
|
||||||
*/
|
*/
|
||||||
function language_negotiation_set($type, $language_providers) {
|
function language_negotiation_set($type, $language_providers) {
|
||||||
@@ -277,7 +367,7 @@ function language_negotiation_set($type, $language_providers) {
|
|||||||
// If the provider does not express any preference about types, make it
|
// If the provider does not express any preference about types, make it
|
||||||
// available for any configurable type.
|
// available for any configurable type.
|
||||||
$types = array_flip(isset($provider['types']) ? $provider['types'] : $default_types);
|
$types = array_flip(isset($provider['types']) ? $provider['types'] : $default_types);
|
||||||
// Check if the provider is defined and has the right type.
|
// Check whether the provider is defined and has the right type.
|
||||||
if (isset($types[$type])) {
|
if (isset($types[$type])) {
|
||||||
$provider_data = array();
|
$provider_data = array();
|
||||||
foreach ($provider_fields as $field) {
|
foreach ($provider_fields as $field) {
|
||||||
@@ -294,10 +384,10 @@ function language_negotiation_set($type, $language_providers) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all the defined language providers.
|
* Returns all the defined language negotiation providers.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* An array of language providers.
|
* An array of language negotiation providers.
|
||||||
*/
|
*/
|
||||||
function language_negotiation_info() {
|
function language_negotiation_info() {
|
||||||
$language_providers = &drupal_static(__FUNCTION__);
|
$language_providers = &drupal_static(__FUNCTION__);
|
||||||
@@ -306,7 +396,7 @@ function language_negotiation_info() {
|
|||||||
// Collect all the module-defined language negotiation providers.
|
// Collect all the module-defined language negotiation providers.
|
||||||
$language_providers = module_invoke_all('language_negotiation_info');
|
$language_providers = module_invoke_all('language_negotiation_info');
|
||||||
|
|
||||||
// Add the default language provider.
|
// Add the default language negotiation provider.
|
||||||
$language_providers[LANGUAGE_NEGOTIATION_DEFAULT] = array(
|
$language_providers[LANGUAGE_NEGOTIATION_DEFAULT] = array(
|
||||||
'callbacks' => array('language' => 'language_from_default'),
|
'callbacks' => array('language' => 'language_from_default'),
|
||||||
'weight' => 10,
|
'weight' => 10,
|
||||||
@@ -314,7 +404,7 @@ function language_negotiation_info() {
|
|||||||
'description' => t('Use the default site language (@language_name).', array('@language_name' => language_default()->native)),
|
'description' => t('Use the default site language (@language_name).', array('@language_name' => language_default()->native)),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Let other modules alter the list of language providers.
|
// Let other modules alter the list of language negotiation providers.
|
||||||
drupal_alter('language_negotiation_info', $language_providers);
|
drupal_alter('language_negotiation_info', $language_providers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,16 +412,17 @@ function language_negotiation_info() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function used to cache the language providers results.
|
* Helper function used to cache the language negotiation providers results.
|
||||||
*
|
*
|
||||||
* @param $provider_id
|
* @param $provider_id
|
||||||
* The language provider ID.
|
* The language negotiation provider's identifier.
|
||||||
* @param $provider
|
* @param $provider
|
||||||
* The language provider to be invoked. If not passed it will be explicitly
|
* (optional) An associative array of information about the provider to be
|
||||||
* loaded through language_negotiation_info().
|
* invoked (see hook_language_negotiation_info() for details). If not passed
|
||||||
|
* in, it will be loaded through language_negotiation_info().
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* The language provider's return value.
|
* A language object representing the language chosen by the provider.
|
||||||
*/
|
*/
|
||||||
function language_provider_invoke($provider_id, $provider = NULL) {
|
function language_provider_invoke($provider_id, $provider = NULL) {
|
||||||
$results = &drupal_static(__FUNCTION__);
|
$results = &drupal_static(__FUNCTION__);
|
||||||
@@ -352,25 +443,26 @@ function language_provider_invoke($provider_id, $provider = NULL) {
|
|||||||
require_once DRUPAL_ROOT . '/' . $provider['file'];
|
require_once DRUPAL_ROOT . '/' . $provider['file'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the language provider has no cache preference or this is satisfied
|
// If the language negotiation provider has no cache preference or this is
|
||||||
// we can execute the callback.
|
// satisfied we can execute the callback.
|
||||||
$cache = !isset($provider['cache']) || $user->uid || $provider['cache'] == variable_get('cache', 0);
|
$cache = !isset($provider['cache']) || $user->uid || $provider['cache'] == variable_get('cache', 0);
|
||||||
$callback = isset($provider['callbacks']['language']) ? $provider['callbacks']['language'] : FALSE;
|
$callback = isset($provider['callbacks']['language']) ? $provider['callbacks']['language'] : FALSE;
|
||||||
$langcode = $cache && function_exists($callback) ? $callback($languages) : FALSE;
|
$langcode = $cache && function_exists($callback) ? $callback($languages) : FALSE;
|
||||||
$results[$provider_id] = isset($languages[$langcode]) ? $languages[$langcode] : FALSE;
|
$results[$provider_id] = isset($languages[$langcode]) ? $languages[$langcode] : FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since objects are resources we need to return a clone to prevent the
|
// Since objects are resources, we need to return a clone to prevent the
|
||||||
// provider cache to be unintentionally altered. The same providers might be
|
// language negotiation provider cache from being unintentionally altered. The
|
||||||
// used with different language types based on configuration.
|
// same providers might be used with different language types based on
|
||||||
|
// configuration.
|
||||||
return !empty($results[$provider_id]) ? clone($results[$provider_id]) : $results[$provider_id];
|
return !empty($results[$provider_id]) ? clone($results[$provider_id]) : $results[$provider_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the passed language provider weight or a default value.
|
* Returns the passed language negotiation provider weight or a default value.
|
||||||
*
|
*
|
||||||
* @param $provider
|
* @param $provider
|
||||||
* A language provider data structure.
|
* A language negotiation provider data structure.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* A numeric weight.
|
* A numeric weight.
|
||||||
@@ -381,16 +473,16 @@ function language_provider_weight($provider) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Choose a language for the given type based on language negotiation settings.
|
* Chooses a language based on language negotiation provider settings.
|
||||||
*
|
*
|
||||||
* @param $type
|
* @param $type
|
||||||
* The language type.
|
* The language type key to find the language for.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* The negotiated language object.
|
* The negotiated language object.
|
||||||
*/
|
*/
|
||||||
function language_initialize($type) {
|
function language_initialize($type) {
|
||||||
// Execute the language providers in the order they were set up and return the
|
// Execute the language negotiation providers in the order they were set up and return the
|
||||||
// first valid language found.
|
// first valid language found.
|
||||||
$negotiation = variable_get("language_negotiation_$type", array());
|
$negotiation = variable_get("language_negotiation_$type", array());
|
||||||
|
|
||||||
@@ -409,7 +501,7 @@ function language_initialize($type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default language provider.
|
* Returns the default language negotiation provider.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* The default language code.
|
* The default language code.
|
||||||
@@ -421,8 +513,8 @@ function language_from_default() {
|
|||||||
/**
|
/**
|
||||||
* Splits the given path into prefix and actual path.
|
* Splits the given path into prefix and actual path.
|
||||||
*
|
*
|
||||||
* Parse the given path and return the language object identified by the
|
* Parse the given path and return the language object identified by the prefix
|
||||||
* prefix and the actual path.
|
* and the actual path.
|
||||||
*
|
*
|
||||||
* @param $path
|
* @param $path
|
||||||
* The path to split.
|
* The path to split.
|
||||||
@@ -482,3 +574,7 @@ function language_fallback_get_candidates($type = LANGUAGE_TYPE_CONTENT) {
|
|||||||
|
|
||||||
return $fallback_candidates;
|
return $fallback_candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @} End of "language_negotiation"
|
||||||
|
*/
|
||||||
|
|||||||
@@ -93,7 +93,9 @@ define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || strpos($_SERVER['SERVER
|
|||||||
* will be {$module}_{$key}.
|
* will be {$module}_{$key}.
|
||||||
* @param $to
|
* @param $to
|
||||||
* The e-mail address or addresses where the message will be sent to. The
|
* The e-mail address or addresses where the message will be sent to. The
|
||||||
* formatting of this string must comply with RFC 2822. Some examples are:
|
* formatting of this string will be validated with the
|
||||||
|
* @link http://php.net/manual/filter.filters.validate.php PHP e-mail validation filter. @endlink
|
||||||
|
* Some examples are:
|
||||||
* - user@example.com
|
* - user@example.com
|
||||||
* - user@example.com, anotheruser@example.com
|
* - user@example.com, anotheruser@example.com
|
||||||
* - User <user@example.com>
|
* - User <user@example.com>
|
||||||
@@ -212,9 +214,9 @@ function drupal_mail($module, $key, $to, $language, $params = array(), $from = N
|
|||||||
* 'mail_system', which is a keyed array. The default implementation
|
* 'mail_system', which is a keyed array. The default implementation
|
||||||
* is the class whose name is the value of 'default-system' key. A more specific
|
* is the class whose name is the value of 'default-system' key. A more specific
|
||||||
* match first to key and then to module will be used in preference to the
|
* match first to key and then to module will be used in preference to the
|
||||||
* default. To specificy a different class for all mail sent by one module, set
|
* default. To specify a different class for all mail sent by one module, set
|
||||||
* the class name as the value for the key corresponding to the module name. To
|
* the class name as the value for the key corresponding to the module name. To
|
||||||
* specificy a class for a particular message sent by one module, set the class
|
* specify a class for a particular message sent by one module, set the class
|
||||||
* name as the value for the array key that is the message id, which is
|
* name as the value for the array key that is the message id, which is
|
||||||
* "${module}_${key}".
|
* "${module}_${key}".
|
||||||
*
|
*
|
||||||
@@ -307,19 +309,21 @@ interface MailSystemInterface {
|
|||||||
* - id: A unique identifier of the e-mail type. Examples: 'contact_user_copy',
|
* - id: A unique identifier of the e-mail type. Examples: 'contact_user_copy',
|
||||||
* 'user_password_reset'.
|
* 'user_password_reset'.
|
||||||
* - to: The mail address or addresses where the message will be sent to.
|
* - to: The mail address or addresses where the message will be sent to.
|
||||||
* The formatting of this string must comply with RFC 2822. Some examples:
|
* The formatting of this string will be validated with the
|
||||||
|
* @link http://php.net/manual/filter.filters.validate.php PHP e-mail validation filter. @endlink
|
||||||
|
* Some examples are:
|
||||||
* - user@example.com
|
* - user@example.com
|
||||||
* - user@example.com, anotheruser@example.com
|
* - user@example.com, anotheruser@example.com
|
||||||
* - User <user@example.com>
|
* - User <user@example.com>
|
||||||
* - User <user@example.com>, Another User <anotheruser@example.com>
|
* - User <user@example.com>, Another User <anotheruser@example.com>
|
||||||
* - subject: Subject of the e-mail to be sent. This must not contain any
|
* - subject: Subject of the e-mail to be sent. This must not contain any
|
||||||
* newline characters, or the mail may not be sent properly.
|
* newline characters, or the mail may not be sent properly.
|
||||||
* - body: Message to be sent. Accepts both CRLF and LF line-endings.
|
* - body: Message to be sent. Accepts both CRLF and LF line-endings.
|
||||||
* E-mail bodies must be wrapped. You can use drupal_wrap_mail() for
|
* E-mail bodies must be wrapped. You can use drupal_wrap_mail() for
|
||||||
* smart plain text wrapping.
|
* smart plain text wrapping.
|
||||||
* - headers: Associative array containing all additional mail headers not
|
* - headers: Associative array containing all additional mail headers not
|
||||||
* defined by one of the other parameters. PHP's mail() looks for Cc
|
* defined by one of the other parameters. PHP's mail() looks for Cc and
|
||||||
* and Bcc headers and sends the mail to addresses in these headers too.
|
* Bcc headers and sends the mail to addresses in these headers too.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* TRUE if the mail was successfully accepted for delivery, otherwise FALSE.
|
* TRUE if the mail was successfully accepted for delivery, otherwise FALSE.
|
||||||
@@ -335,13 +339,13 @@ interface MailSystemInterface {
|
|||||||
*
|
*
|
||||||
* We deliberately use LF rather than CRLF, see drupal_mail().
|
* We deliberately use LF rather than CRLF, see drupal_mail().
|
||||||
*
|
*
|
||||||
* @param $text
|
* @param string $text
|
||||||
* The plain text to process.
|
* The plain text to process.
|
||||||
* @param $indent (optional)
|
* @param string $indent (optional)
|
||||||
* A string to indent the text with. Only '>' characters are repeated on
|
* A string to indent the text with. Only '>' characters are repeated on
|
||||||
* subsequent wrapped lines. Others are replaced by spaces.
|
* subsequent wrapped lines. Others are replaced by spaces.
|
||||||
*
|
*
|
||||||
* @return
|
* @return string
|
||||||
* The content of the email as a string with formatting applied.
|
* The content of the email as a string with formatting applied.
|
||||||
*/
|
*/
|
||||||
function drupal_wrap_mail($text, $indent = '') {
|
function drupal_wrap_mail($text, $indent = '') {
|
||||||
@@ -352,8 +356,9 @@ function drupal_wrap_mail($text, $indent = '') {
|
|||||||
$soft = strpos($clean_indent, ' ') === FALSE;
|
$soft = strpos($clean_indent, ' ') === FALSE;
|
||||||
// Check if the string has line breaks.
|
// Check if the string has line breaks.
|
||||||
if (strpos($text, "\n") !== FALSE) {
|
if (strpos($text, "\n") !== FALSE) {
|
||||||
// Remove trailing spaces to make existing breaks hard.
|
// Remove trailing spaces to make existing breaks hard, but leave signature
|
||||||
$text = preg_replace('/ +\n/m', "\n", $text);
|
// marker untouched (RFC 3676, Section 4.3).
|
||||||
|
$text = preg_replace('/(?(?<!^--) +\n| +\n)/m', "\n", $text);
|
||||||
// Wrap each line at the needed width.
|
// Wrap each line at the needed width.
|
||||||
$lines = explode("\n", $text);
|
$lines = explode("\n", $text);
|
||||||
array_walk($lines, '_drupal_wrap_mail_line', array('soft' => $soft, 'length' => strlen($indent)));
|
array_walk($lines, '_drupal_wrap_mail_line', array('soft' => $soft, 'length' => strlen($indent)));
|
||||||
@@ -559,7 +564,7 @@ function drupal_html_to_text($string, $allowed_tags = NULL) {
|
|||||||
*/
|
*/
|
||||||
function _drupal_wrap_mail_line(&$line, $key, $values) {
|
function _drupal_wrap_mail_line(&$line, $key, $values) {
|
||||||
// Use soft-breaks only for purely quoted or unindented text.
|
// Use soft-breaks only for purely quoted or unindented text.
|
||||||
$line = wordwrap($line, 77 - $values['length'], $values['soft'] ? " \n" : "\n");
|
$line = wordwrap($line, 77 - $values['length'], $values['soft'] ? " \n" : "\n");
|
||||||
// Break really long words at the maximum width allowed.
|
// Break really long words at the maximum width allowed.
|
||||||
$line = wordwrap($line, 996 - $values['length'], $values['soft'] ? " \n" : "\n");
|
$line = wordwrap($line, 996 - $values['length'], $values['soft'] ? " \n" : "\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ define('MENU_PREFERRED_LINK', '1cf698d64d1aa4b83907cf6ed55db3a7f8e92c91');
|
|||||||
* actually exists. This list of 'masks' is built in menu_rebuild().
|
* actually exists. This list of 'masks' is built in menu_rebuild().
|
||||||
*
|
*
|
||||||
* @param $parts
|
* @param $parts
|
||||||
* An array of path parts, for the above example
|
* An array of path parts; for the above example,
|
||||||
* array('node', '12345', 'edit').
|
* array('node', '12345', 'edit').
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
@@ -430,7 +430,7 @@ function menu_set_item($path, $router_item) {
|
|||||||
* Gets a router item.
|
* Gets a router item.
|
||||||
*
|
*
|
||||||
* @param $path
|
* @param $path
|
||||||
* The path, for example node/5. The function will find the corresponding
|
* The path; for example, 'node/5'. The function will find the corresponding
|
||||||
* node/% item and return that.
|
* node/% item and return that.
|
||||||
* @param $router_item
|
* @param $router_item
|
||||||
* Internal use only.
|
* Internal use only.
|
||||||
@@ -542,7 +542,7 @@ function menu_execute_active_handler($path = NULL, $deliver = TRUE) {
|
|||||||
* @param $item
|
* @param $item
|
||||||
* A menu router or menu link item
|
* A menu router or menu link item
|
||||||
* @param $map
|
* @param $map
|
||||||
* An array of path arguments (ex: array('node', '5'))
|
* An array of path arguments; for example, array('node', '5').
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* Returns TRUE for success, FALSE if an object cannot be loaded.
|
* Returns TRUE for success, FALSE if an object cannot be loaded.
|
||||||
@@ -612,12 +612,13 @@ function _menu_load_objects(&$item, &$map) {
|
|||||||
* @param $item
|
* @param $item
|
||||||
* A menu router or menu link item
|
* A menu router or menu link item
|
||||||
* @param $map
|
* @param $map
|
||||||
* An array of path arguments (ex: array('node', '5'))
|
* An array of path arguments; for example, array('node', '5').
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* $item['access'] becomes TRUE if the item is accessible, FALSE otherwise.
|
* $item['access'] becomes TRUE if the item is accessible, FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
function _menu_check_access(&$item, $map) {
|
function _menu_check_access(&$item, $map) {
|
||||||
|
$item['access'] = FALSE;
|
||||||
// Determine access callback, which will decide whether or not the current
|
// Determine access callback, which will decide whether or not the current
|
||||||
// user has access to this path.
|
// user has access to this path.
|
||||||
$callback = empty($item['access_callback']) ? 0 : trim($item['access_callback']);
|
$callback = empty($item['access_callback']) ? 0 : trim($item['access_callback']);
|
||||||
@@ -737,7 +738,7 @@ function _menu_item_localize(&$item, $map, $link_translate = FALSE) {
|
|||||||
* @param $router_item
|
* @param $router_item
|
||||||
* A menu router item
|
* A menu router item
|
||||||
* @param $map
|
* @param $map
|
||||||
* An array of path arguments (ex: array('node', '5'))
|
* An array of path arguments; for example, array('node', '5').
|
||||||
* @param $to_arg
|
* @param $to_arg
|
||||||
* Execute $item['to_arg_functions'] or not. Use only if you want to render a
|
* Execute $item['to_arg_functions'] or not. Use only if you want to render a
|
||||||
* path from the menu table, for example tabs.
|
* path from the menu table, for example tabs.
|
||||||
@@ -800,9 +801,9 @@ function _menu_translate(&$router_item, $map, $to_arg = FALSE) {
|
|||||||
* Translates the path elements in the map using any to_arg helper function.
|
* Translates the path elements in the map using any to_arg helper function.
|
||||||
*
|
*
|
||||||
* @param $map
|
* @param $map
|
||||||
* An array of path arguments (ex: array('node', '5'))
|
* An array of path arguments; for example, array('node', '5').
|
||||||
* @param $to_arg_functions
|
* @param $to_arg_functions
|
||||||
* An array of helper function (ex: array(2 => 'menu_tail_to_arg'))
|
* An array of helper functions; for example, array(2 => 'menu_tail_to_arg').
|
||||||
*
|
*
|
||||||
* @see hook_menu()
|
* @see hook_menu()
|
||||||
*/
|
*/
|
||||||
@@ -999,7 +1000,7 @@ function menu_tree($menu_name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a rendered menu tree.
|
* Returns an output structure for rendering a menu tree.
|
||||||
*
|
*
|
||||||
* The menu item's LI element is given one of the following classes:
|
* The menu item's LI element is given one of the following classes:
|
||||||
* - expanded: The menu item is showing its submenu.
|
* - expanded: The menu item is showing its submenu.
|
||||||
@@ -1925,13 +1926,21 @@ function menu_local_tasks($level = 0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get all tabs (also known as local tasks) and the root page.
|
// Get all tabs (also known as local tasks) and the root page.
|
||||||
$result = db_select('menu_router', NULL, array('fetch' => PDO::FETCH_ASSOC))
|
$cid = 'local_tasks:' . $router_item['tab_root'];
|
||||||
->fields('menu_router')
|
if ($cache = cache_get($cid, 'cache_menu')) {
|
||||||
->condition('tab_root', $router_item['tab_root'])
|
$result = $cache->data;
|
||||||
->condition('context', MENU_CONTEXT_INLINE, '<>')
|
}
|
||||||
->orderBy('weight')
|
else {
|
||||||
->orderBy('title')
|
$result = db_select('menu_router', NULL, array('fetch' => PDO::FETCH_ASSOC))
|
||||||
->execute();
|
->fields('menu_router')
|
||||||
|
->condition('tab_root', $router_item['tab_root'])
|
||||||
|
->condition('context', MENU_CONTEXT_INLINE, '<>')
|
||||||
|
->orderBy('weight')
|
||||||
|
->orderBy('title')
|
||||||
|
->execute()
|
||||||
|
->fetchAll();
|
||||||
|
cache_set($cid, $result, 'cache_menu');
|
||||||
|
}
|
||||||
$map = $router_item['original_map'];
|
$map = $router_item['original_map'];
|
||||||
$children = array();
|
$children = array();
|
||||||
$tasks = array();
|
$tasks = array();
|
||||||
@@ -2138,7 +2147,7 @@ function menu_local_tasks($level = 0) {
|
|||||||
* example 'node' or 'admin/structure/block/manage'.
|
* example 'node' or 'admin/structure/block/manage'.
|
||||||
* @param $args
|
* @param $args
|
||||||
* A list of dynamic path arguments to append to $parent_path to form the
|
* A list of dynamic path arguments to append to $parent_path to form the
|
||||||
* fully-qualified menu router path, for example array(123) for a certain
|
* fully-qualified menu router path; for example, array(123) for a certain
|
||||||
* node or array('system', 'navigation') for a certain block.
|
* node or array('system', 'navigation') for a certain block.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
@@ -2429,7 +2438,7 @@ function menu_set_active_trail($new_trail = NULL) {
|
|||||||
* Looks up the preferred menu link for a given system path.
|
* Looks up the preferred menu link for a given system path.
|
||||||
*
|
*
|
||||||
* @param $path
|
* @param $path
|
||||||
* The path, for example 'node/5'. The function will find the corresponding
|
* The path; for example, 'node/5'. The function will find the corresponding
|
||||||
* menu link ('node/5' if it exists, or fallback to 'node/%').
|
* menu link ('node/5' if it exists, or fallback to 'node/%').
|
||||||
* @param $selected_menu
|
* @param $selected_menu
|
||||||
* The name of a menu used to restrict the search for a preferred menu link.
|
* The name of a menu used to restrict the search for a preferred menu link.
|
||||||
|
|||||||
@@ -610,9 +610,40 @@ function module_disable($module_list, $disable_dependents = TRUE) {
|
|||||||
* just models that you can modify. Only the hooks implemented within modules
|
* just models that you can modify. Only the hooks implemented within modules
|
||||||
* are executed when running Drupal.
|
* are executed when running Drupal.
|
||||||
*
|
*
|
||||||
* See also @link themeable the themeable group page. @endlink
|
* @see themeable
|
||||||
|
* @see callbacks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup callbacks Callbacks
|
||||||
|
* @{
|
||||||
|
* Callback function signatures.
|
||||||
|
*
|
||||||
|
* Drupal's API sometimes uses callback functions to allow you to define how
|
||||||
|
* some type of processing happens. A callback is a function with a defined
|
||||||
|
* signature, which you define in a module. Then you pass the function name as
|
||||||
|
* a parameter to a Drupal API function or return it as part of a hook
|
||||||
|
* implementation return value, and your function is called at an appropriate
|
||||||
|
* time. For instance, when setting up batch processing you might need to
|
||||||
|
* provide a callback function for each processing step and/or a callback for
|
||||||
|
* when processing is finished; you would do that by defining these functions
|
||||||
|
* and passing their names into the batch setup function.
|
||||||
|
*
|
||||||
|
* Callback function signatures, like hook definitions, are described by
|
||||||
|
* creating and documenting dummy functions in a *.api.php file; normally, the
|
||||||
|
* dummy callback function's name should start with "callback_", and you should
|
||||||
|
* document the parameters and return value and provide a sample function body.
|
||||||
|
* Then your API documentation can refer to this callback function in its
|
||||||
|
* documentation. A user of your API can usually name their callback function
|
||||||
|
* anything they want, although a standard name would be to replace "callback_"
|
||||||
|
* with the module name.
|
||||||
|
*
|
||||||
|
* @see hooks
|
||||||
|
* @see themeable
|
||||||
|
*
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether a module implements a hook.
|
* Determines whether a module implements a hook.
|
||||||
*
|
*
|
||||||
@@ -803,10 +834,7 @@ function module_hook_info() {
|
|||||||
*/
|
*/
|
||||||
function module_implements_write_cache() {
|
function module_implements_write_cache() {
|
||||||
$implementations = &drupal_static('module_implements');
|
$implementations = &drupal_static('module_implements');
|
||||||
// Check whether we need to write the cache. We do not want to cache hooks
|
if (isset($implementations['#write_cache'])) {
|
||||||
// which are only invoked on HTTP POST requests since these do not need to be
|
|
||||||
// optimized as tightly, and not doing so keeps the cache entry smaller.
|
|
||||||
if (isset($implementations['#write_cache']) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD')) {
|
|
||||||
unset($implementations['#write_cache']);
|
unset($implementations['#write_cache']);
|
||||||
cache_set('module_implements', $implementations, 'cache_bootstrap');
|
cache_set('module_implements', $implementations, 'cache_bootstrap');
|
||||||
}
|
}
|
||||||
@@ -815,6 +843,9 @@ function module_implements_write_cache() {
|
|||||||
/**
|
/**
|
||||||
* Invokes a hook in a particular module.
|
* Invokes a hook in a particular module.
|
||||||
*
|
*
|
||||||
|
* All arguments are passed by value. Use drupal_alter() if you need to pass
|
||||||
|
* arguments by reference.
|
||||||
|
*
|
||||||
* @param $module
|
* @param $module
|
||||||
* The name of the module (without the .module extension).
|
* The name of the module (without the .module extension).
|
||||||
* @param $hook
|
* @param $hook
|
||||||
@@ -824,6 +855,8 @@ function module_implements_write_cache() {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* The return value of the hook implementation.
|
* The return value of the hook implementation.
|
||||||
|
*
|
||||||
|
* @see drupal_alter()
|
||||||
*/
|
*/
|
||||||
function module_invoke($module, $hook) {
|
function module_invoke($module, $hook) {
|
||||||
$args = func_get_args();
|
$args = func_get_args();
|
||||||
@@ -837,6 +870,9 @@ function module_invoke($module, $hook) {
|
|||||||
/**
|
/**
|
||||||
* Invokes a hook in all enabled modules that implement it.
|
* Invokes a hook in all enabled modules that implement it.
|
||||||
*
|
*
|
||||||
|
* All arguments are passed by value. Use drupal_alter() if you need to pass
|
||||||
|
* arguments by reference.
|
||||||
|
*
|
||||||
* @param $hook
|
* @param $hook
|
||||||
* The name of the hook to invoke.
|
* The name of the hook to invoke.
|
||||||
* @param ...
|
* @param ...
|
||||||
@@ -845,6 +881,8 @@ function module_invoke($module, $hook) {
|
|||||||
* @return
|
* @return
|
||||||
* An array of return values of the hook implementations. If modules return
|
* An array of return values of the hook implementations. If modules return
|
||||||
* arrays from their implementations, those are merged into one array.
|
* arrays from their implementations, those are merged into one array.
|
||||||
|
*
|
||||||
|
* @see drupal_alter()
|
||||||
*/
|
*/
|
||||||
function module_invoke_all($hook) {
|
function module_invoke_all($hook) {
|
||||||
$args = func_get_args();
|
$args = func_get_args();
|
||||||
@@ -898,9 +936,10 @@ function drupal_required_modules() {
|
|||||||
* hook_TYPE_alter() implementations in modules. It ensures a consistent
|
* hook_TYPE_alter() implementations in modules. It ensures a consistent
|
||||||
* interface for all altering operations.
|
* interface for all altering operations.
|
||||||
*
|
*
|
||||||
* A maximum of 2 alterable arguments is supported. In case more arguments need
|
* A maximum of 2 alterable arguments is supported (a third is supported for
|
||||||
* to be passed and alterable, modules provide additional variables assigned by
|
* legacy reasons, but should not be used in new code). In case more arguments
|
||||||
* reference in the last $context argument:
|
* need to be passed and alterable, modules provide additional variables
|
||||||
|
* assigned by reference in the last $context argument:
|
||||||
* @code
|
* @code
|
||||||
* $context = array(
|
* $context = array(
|
||||||
* 'alterable' => &$alterable,
|
* 'alterable' => &$alterable,
|
||||||
@@ -939,8 +978,14 @@ function drupal_required_modules() {
|
|||||||
* (optional) An additional variable that is passed by reference. If more
|
* (optional) An additional variable that is passed by reference. If more
|
||||||
* context needs to be provided to implementations, then this should be an
|
* context needs to be provided to implementations, then this should be an
|
||||||
* associative array as described above.
|
* associative array as described above.
|
||||||
|
* @param $context3
|
||||||
|
* (optional) An additional variable that is passed by reference. This
|
||||||
|
* parameter is deprecated and will not exist in Drupal 8; consequently, it
|
||||||
|
* should not be used for new Drupal 7 code either. It is here only for
|
||||||
|
* backwards compatibility with older code that passed additional arguments
|
||||||
|
* to drupal_alter().
|
||||||
*/
|
*/
|
||||||
function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
|
function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL, &$context3 = NULL) {
|
||||||
// Use the advanced drupal_static() pattern, since this is called very often.
|
// Use the advanced drupal_static() pattern, since this is called very often.
|
||||||
static $drupal_static_fast;
|
static $drupal_static_fast;
|
||||||
if (!isset($drupal_static_fast)) {
|
if (!isset($drupal_static_fast)) {
|
||||||
@@ -1053,6 +1098,6 @@ function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($functions[$cid] as $function) {
|
foreach ($functions[$cid] as $function) {
|
||||||
$function($data, $context1, $context2);
|
$function($data, $context1, $context2, $context3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ function _password_itoa64() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode bytes into printable base 64 using the *nix standard from crypt().
|
* Encodes bytes into printable base 64 using the *nix standard from crypt().
|
||||||
*
|
*
|
||||||
* @param $input
|
* @param $input
|
||||||
* The string containing bytes to encode.
|
* The string containing bytes to encode.
|
||||||
|
|||||||
@@ -386,7 +386,7 @@ function drupal_path_alias_whitelist_rebuild($source = NULL) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch a specific URL alias from the database.
|
* Fetches a specific URL alias from the database.
|
||||||
*
|
*
|
||||||
* @param $conditions
|
* @param $conditions
|
||||||
* A string representing the source, a number representing the pid, or an
|
* A string representing the source, a number representing the pid, or an
|
||||||
@@ -475,11 +475,11 @@ function path_delete($criteria) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether a path is in the administrative section of the site.
|
* Determines whether a path is in the administrative section of the site.
|
||||||
*
|
*
|
||||||
* By default, paths are considered to be non-administrative. If a path does not
|
* By default, paths are considered to be non-administrative. If a path does
|
||||||
* match any of the patterns in path_get_admin_paths(), or if it matches both
|
* not match any of the patterns in path_get_admin_paths(), or if it matches
|
||||||
* administrative and non-administrative patterns, it is considered
|
* both administrative and non-administrative patterns, it is considered
|
||||||
* non-administrative.
|
* non-administrative.
|
||||||
*
|
*
|
||||||
* @param $path
|
* @param $path
|
||||||
@@ -503,7 +503,7 @@ function path_is_admin($path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of administrative and non-administrative paths.
|
* Gets a list of administrative and non-administrative paths.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* An associative array containing the following keys:
|
* An associative array containing the following keys:
|
||||||
@@ -560,8 +560,8 @@ function drupal_valid_path($path, $dynamic_allowed = FALSE) {
|
|||||||
elseif ($dynamic_allowed && preg_match('/\/\%/', $path)) {
|
elseif ($dynamic_allowed && preg_match('/\/\%/', $path)) {
|
||||||
// Path is dynamic (ie 'user/%'), so check directly against menu_router table.
|
// Path is dynamic (ie 'user/%'), so check directly against menu_router table.
|
||||||
if ($item = db_query("SELECT * FROM {menu_router} where path = :path", array(':path' => $path))->fetchAssoc()) {
|
if ($item = db_query("SELECT * FROM {menu_router} where path = :path", array(':path' => $path))->fetchAssoc()) {
|
||||||
$item['link_path'] = $form_item['link_path'];
|
$item['link_path'] = $item['path'];
|
||||||
$item['link_title'] = $form_item['link_title'];
|
$item['link_title'] = $item['title'];
|
||||||
$item['external'] = FALSE;
|
$item['external'] = FALSE;
|
||||||
$item['options'] = '';
|
$item['options'] = '';
|
||||||
_menu_link_translate($item);
|
_menu_link_translate($item);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
* @{
|
* @{
|
||||||
* The code registry engine.
|
* The code registry engine.
|
||||||
*
|
*
|
||||||
* Drupal maintains an internal registry of all functions or classes in the
|
* Drupal maintains an internal registry of all interfaces or classes in the
|
||||||
* system, allowing it to lazy-load code files as needed (reducing the amount
|
* system, allowing it to lazy-load code files as needed (reducing the amount
|
||||||
* of code that must be parsed on each request).
|
* of code that must be parsed on each request).
|
||||||
*/
|
*/
|
||||||
@@ -120,7 +120,10 @@ function registry_get_parsed_files() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse all files that have changed since the registry was last built, and save their function and class listings.
|
* Parse all changed files and save their interface and class listings.
|
||||||
|
*
|
||||||
|
* Parse all files that have changed since the registry was last built, and save
|
||||||
|
* their interface and class listings.
|
||||||
*
|
*
|
||||||
* @param $files
|
* @param $files
|
||||||
* The list of files to check and parse.
|
* The list of files to check and parse.
|
||||||
@@ -149,7 +152,7 @@ function _registry_parse_files($files) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a file and save its function and class listings.
|
* Parse a file and save its interface and class listings.
|
||||||
*
|
*
|
||||||
* @param $filename
|
* @param $filename
|
||||||
* Name of the file we are going to parse.
|
* Name of the file we are going to parse.
|
||||||
|
|||||||
@@ -263,10 +263,10 @@ function drupal_session_initialize() {
|
|||||||
// Less random sessions (which are much faster to generate) are used for
|
// Less random sessions (which are much faster to generate) are used for
|
||||||
// anonymous users than are generated in drupal_session_regenerate() when
|
// anonymous users than are generated in drupal_session_regenerate() when
|
||||||
// a user becomes authenticated.
|
// a user becomes authenticated.
|
||||||
session_id(drupal_hash_base64(uniqid(mt_rand(), TRUE)));
|
session_id(drupal_random_key());
|
||||||
if ($is_https && variable_get('https', FALSE)) {
|
if ($is_https && variable_get('https', FALSE)) {
|
||||||
$insecure_session_name = substr(session_name(), 1);
|
$insecure_session_name = substr(session_name(), 1);
|
||||||
$session_id = drupal_hash_base64(uniqid(mt_rand(), TRUE));
|
$session_id = drupal_random_key();
|
||||||
$_COOKIE[$insecure_session_name] = $session_id;
|
$_COOKIE[$insecure_session_name] = $session_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,7 +274,7 @@ function drupal_session_initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forcefully starts a session, preserving already set session data.
|
* Starts a session forcefully, preserving already set session data.
|
||||||
*
|
*
|
||||||
* @ingroup php_wrappers
|
* @ingroup php_wrappers
|
||||||
*/
|
*/
|
||||||
@@ -360,7 +360,7 @@ function drupal_session_regenerate() {
|
|||||||
$old_insecure_session_id = $_COOKIE[$insecure_session_name];
|
$old_insecure_session_id = $_COOKIE[$insecure_session_name];
|
||||||
}
|
}
|
||||||
$params = session_get_cookie_params();
|
$params = session_get_cookie_params();
|
||||||
$session_id = drupal_hash_base64(uniqid(mt_rand(), TRUE) . drupal_random_bytes(55));
|
$session_id = drupal_random_key();
|
||||||
// If a session cookie lifetime is set, the session will expire
|
// If a session cookie lifetime is set, the session will expire
|
||||||
// $params['lifetime'] seconds from the current request. If it is not set,
|
// $params['lifetime'] seconds from the current request. If it is not set,
|
||||||
// it will expire when the browser is closed.
|
// it will expire when the browser is closed.
|
||||||
@@ -372,7 +372,7 @@ function drupal_session_regenerate() {
|
|||||||
if (drupal_session_started()) {
|
if (drupal_session_started()) {
|
||||||
$old_session_id = session_id();
|
$old_session_id = session_id();
|
||||||
}
|
}
|
||||||
session_id(drupal_hash_base64(uniqid(mt_rand(), TRUE) . drupal_random_bytes(55)));
|
session_id(drupal_random_key());
|
||||||
|
|
||||||
if (isset($old_session_id)) {
|
if (isset($old_session_id)) {
|
||||||
$params = session_get_cookie_params();
|
$params = session_get_cookie_params();
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ define('STREAM_WRAPPERS_LOCAL_NORMAL', STREAM_WRAPPERS_LOCAL | STREAM_WRAPPERS_N
|
|||||||
/**
|
/**
|
||||||
* Generic PHP stream wrapper interface.
|
* Generic PHP stream wrapper interface.
|
||||||
*
|
*
|
||||||
* @see http://www.php.net/manual/en/class.streamwrapper.php
|
* @see http://www.php.net/manual/class.streamwrapper.php
|
||||||
*/
|
*/
|
||||||
interface StreamWrapperInterface {
|
interface StreamWrapperInterface {
|
||||||
public function stream_open($uri, $mode, $options, &$opened_url);
|
public function stream_open($uri, $mode, $options, &$opened_url);
|
||||||
@@ -401,7 +401,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* @return
|
* @return
|
||||||
* Returns TRUE if file was opened successfully.
|
* Returns TRUE if file was opened successfully.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.stream-open.php
|
* @see http://php.net/manual/streamwrapper.stream-open.php
|
||||||
*/
|
*/
|
||||||
public function stream_open($uri, $mode, $options, &$opened_path) {
|
public function stream_open($uri, $mode, $options, &$opened_path) {
|
||||||
$this->uri = $uri;
|
$this->uri = $uri;
|
||||||
@@ -429,7 +429,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* @return
|
* @return
|
||||||
* Always returns TRUE at the present time.
|
* Always returns TRUE at the present time.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.stream-lock.php
|
* @see http://php.net/manual/streamwrapper.stream-lock.php
|
||||||
*/
|
*/
|
||||||
public function stream_lock($operation) {
|
public function stream_lock($operation) {
|
||||||
if (in_array($operation, array(LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB))) {
|
if (in_array($operation, array(LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB))) {
|
||||||
@@ -448,7 +448,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* @return
|
* @return
|
||||||
* The string that was read, or FALSE in case of an error.
|
* The string that was read, or FALSE in case of an error.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.stream-read.php
|
* @see http://php.net/manual/streamwrapper.stream-read.php
|
||||||
*/
|
*/
|
||||||
public function stream_read($count) {
|
public function stream_read($count) {
|
||||||
return fread($this->handle, $count);
|
return fread($this->handle, $count);
|
||||||
@@ -463,7 +463,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* @return
|
* @return
|
||||||
* The number of bytes written (integer).
|
* The number of bytes written (integer).
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.stream-write.php
|
* @see http://php.net/manual/streamwrapper.stream-write.php
|
||||||
*/
|
*/
|
||||||
public function stream_write($data) {
|
public function stream_write($data) {
|
||||||
return fwrite($this->handle, $data);
|
return fwrite($this->handle, $data);
|
||||||
@@ -475,7 +475,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* @return
|
* @return
|
||||||
* TRUE if end-of-file has been reached.
|
* TRUE if end-of-file has been reached.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.stream-eof.php
|
* @see http://php.net/manual/streamwrapper.stream-eof.php
|
||||||
*/
|
*/
|
||||||
public function stream_eof() {
|
public function stream_eof() {
|
||||||
return feof($this->handle);
|
return feof($this->handle);
|
||||||
@@ -492,7 +492,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* @return
|
* @return
|
||||||
* TRUE on success.
|
* TRUE on success.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.stream-seek.php
|
* @see http://php.net/manual/streamwrapper.stream-seek.php
|
||||||
*/
|
*/
|
||||||
public function stream_seek($offset, $whence) {
|
public function stream_seek($offset, $whence) {
|
||||||
// fseek returns 0 on success and -1 on a failure.
|
// fseek returns 0 on success and -1 on a failure.
|
||||||
@@ -506,7 +506,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* @return
|
* @return
|
||||||
* TRUE if data was successfully stored (or there was no data to store).
|
* TRUE if data was successfully stored (or there was no data to store).
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.stream-flush.php
|
* @see http://php.net/manual/streamwrapper.stream-flush.php
|
||||||
*/
|
*/
|
||||||
public function stream_flush() {
|
public function stream_flush() {
|
||||||
return fflush($this->handle);
|
return fflush($this->handle);
|
||||||
@@ -518,7 +518,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* @return
|
* @return
|
||||||
* The current offset in bytes from the beginning of file.
|
* The current offset in bytes from the beginning of file.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.stream-tell.php
|
* @see http://php.net/manual/streamwrapper.stream-tell.php
|
||||||
*/
|
*/
|
||||||
public function stream_tell() {
|
public function stream_tell() {
|
||||||
return ftell($this->handle);
|
return ftell($this->handle);
|
||||||
@@ -531,7 +531,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* An array with file status, or FALSE in case of an error - see fstat()
|
* An array with file status, or FALSE in case of an error - see fstat()
|
||||||
* for a description of this array.
|
* for a description of this array.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.stream-stat.php
|
* @see http://php.net/manual/streamwrapper.stream-stat.php
|
||||||
*/
|
*/
|
||||||
public function stream_stat() {
|
public function stream_stat() {
|
||||||
return fstat($this->handle);
|
return fstat($this->handle);
|
||||||
@@ -543,7 +543,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* @return
|
* @return
|
||||||
* TRUE if stream was successfully closed.
|
* TRUE if stream was successfully closed.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.stream-close.php
|
* @see http://php.net/manual/streamwrapper.stream-close.php
|
||||||
*/
|
*/
|
||||||
public function stream_close() {
|
public function stream_close() {
|
||||||
return fclose($this->handle);
|
return fclose($this->handle);
|
||||||
@@ -558,7 +558,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* @return
|
* @return
|
||||||
* TRUE if resource was successfully deleted.
|
* TRUE if resource was successfully deleted.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.unlink.php
|
* @see http://php.net/manual/streamwrapper.unlink.php
|
||||||
*/
|
*/
|
||||||
public function unlink($uri) {
|
public function unlink($uri) {
|
||||||
$this->uri = $uri;
|
$this->uri = $uri;
|
||||||
@@ -576,7 +576,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* @return
|
* @return
|
||||||
* TRUE if file was successfully renamed.
|
* TRUE if file was successfully renamed.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.rename.php
|
* @see http://php.net/manual/streamwrapper.rename.php
|
||||||
*/
|
*/
|
||||||
public function rename($from_uri, $to_uri) {
|
public function rename($from_uri, $to_uri) {
|
||||||
return rename($this->getLocalPath($from_uri), $this->getLocalPath($to_uri));
|
return rename($this->getLocalPath($from_uri), $this->getLocalPath($to_uri));
|
||||||
@@ -622,7 +622,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* @return
|
* @return
|
||||||
* TRUE if directory was successfully created.
|
* TRUE if directory was successfully created.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.mkdir.php
|
* @see http://php.net/manual/streamwrapper.mkdir.php
|
||||||
*/
|
*/
|
||||||
public function mkdir($uri, $mode, $options) {
|
public function mkdir($uri, $mode, $options) {
|
||||||
$this->uri = $uri;
|
$this->uri = $uri;
|
||||||
@@ -654,7 +654,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* @return
|
* @return
|
||||||
* TRUE if directory was successfully removed.
|
* TRUE if directory was successfully removed.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.rmdir.php
|
* @see http://php.net/manual/streamwrapper.rmdir.php
|
||||||
*/
|
*/
|
||||||
public function rmdir($uri, $options) {
|
public function rmdir($uri, $options) {
|
||||||
$this->uri = $uri;
|
$this->uri = $uri;
|
||||||
@@ -678,7 +678,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* An array with file status, or FALSE in case of an error - see fstat()
|
* An array with file status, or FALSE in case of an error - see fstat()
|
||||||
* for a description of this array.
|
* for a description of this array.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.url-stat.php
|
* @see http://php.net/manual/streamwrapper.url-stat.php
|
||||||
*/
|
*/
|
||||||
public function url_stat($uri, $flags) {
|
public function url_stat($uri, $flags) {
|
||||||
$this->uri = $uri;
|
$this->uri = $uri;
|
||||||
@@ -704,7 +704,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* @return
|
* @return
|
||||||
* TRUE on success.
|
* TRUE on success.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.dir-opendir.php
|
* @see http://php.net/manual/streamwrapper.dir-opendir.php
|
||||||
*/
|
*/
|
||||||
public function dir_opendir($uri, $options) {
|
public function dir_opendir($uri, $options) {
|
||||||
$this->uri = $uri;
|
$this->uri = $uri;
|
||||||
@@ -719,7 +719,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* @return
|
* @return
|
||||||
* The next filename, or FALSE if there are no more files in the directory.
|
* The next filename, or FALSE if there are no more files in the directory.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.dir-readdir.php
|
* @see http://php.net/manual/streamwrapper.dir-readdir.php
|
||||||
*/
|
*/
|
||||||
public function dir_readdir() {
|
public function dir_readdir() {
|
||||||
return readdir($this->handle);
|
return readdir($this->handle);
|
||||||
@@ -731,7 +731,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* @return
|
* @return
|
||||||
* TRUE on success.
|
* TRUE on success.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.dir-rewinddir.php
|
* @see http://php.net/manual/streamwrapper.dir-rewinddir.php
|
||||||
*/
|
*/
|
||||||
public function dir_rewinddir() {
|
public function dir_rewinddir() {
|
||||||
rewinddir($this->handle);
|
rewinddir($this->handle);
|
||||||
@@ -747,7 +747,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
* @return
|
* @return
|
||||||
* TRUE on success.
|
* TRUE on success.
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/streamwrapper.dir-closedir.php
|
* @see http://php.net/manual/streamwrapper.dir-closedir.php
|
||||||
*/
|
*/
|
||||||
public function dir_closedir() {
|
public function dir_closedir() {
|
||||||
closedir($this->handle);
|
closedir($this->handle);
|
||||||
@@ -788,8 +788,6 @@ class DrupalPublicStreamWrapper extends DrupalLocalStreamWrapper {
|
|||||||
*
|
*
|
||||||
* Provides support for storing privately accessible files with the Drupal file
|
* Provides support for storing privately accessible files with the Drupal file
|
||||||
* interface.
|
* interface.
|
||||||
*
|
|
||||||
* Extends DrupalPublicStreamWrapper.
|
|
||||||
*/
|
*/
|
||||||
class DrupalPrivateStreamWrapper extends DrupalLocalStreamWrapper {
|
class DrupalPrivateStreamWrapper extends DrupalLocalStreamWrapper {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class TableSort extends SelectQueryExtender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the table sort context.
|
* Initializes the table sort context.
|
||||||
*/
|
*/
|
||||||
protected function init() {
|
protected function init() {
|
||||||
$ts = $this->order();
|
$ts = $this->order();
|
||||||
@@ -115,7 +115,7 @@ function tablesort_init($header) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a column header.
|
* Formats a column header.
|
||||||
*
|
*
|
||||||
* If the cell in question is the column header for the current sort criterion,
|
* If the cell in question is the column header for the current sort criterion,
|
||||||
* it gets special formatting. All possible sort criteria become links.
|
* it gets special formatting. All possible sort criteria become links.
|
||||||
@@ -126,6 +126,7 @@ function tablesort_init($header) {
|
|||||||
* An array of column headers in the format described in theme_table().
|
* An array of column headers in the format described in theme_table().
|
||||||
* @param $ts
|
* @param $ts
|
||||||
* The current table sort context as returned from tablesort_init().
|
* The current table sort context as returned from tablesort_init().
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
* A properly formatted cell, ready for _theme_table_cell().
|
* A properly formatted cell, ready for _theme_table_cell().
|
||||||
*/
|
*/
|
||||||
@@ -151,7 +152,7 @@ function tablesort_header($cell, $header, $ts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a table cell.
|
* Formats a table cell.
|
||||||
*
|
*
|
||||||
* Adds a class attribute to all cells in the currently active column.
|
* Adds a class attribute to all cells in the currently active column.
|
||||||
*
|
*
|
||||||
@@ -163,6 +164,7 @@ function tablesort_header($cell, $header, $ts) {
|
|||||||
* The current table sort context as returned from tablesort_init().
|
* The current table sort context as returned from tablesort_init().
|
||||||
* @param $i
|
* @param $i
|
||||||
* The index of the cell's table column.
|
* The index of the cell's table column.
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
* A properly formatted cell, ready for _theme_table_cell().
|
* A properly formatted cell, ready for _theme_table_cell().
|
||||||
*/
|
*/
|
||||||
@@ -179,7 +181,7 @@ function tablesort_cell($cell, $header, $ts, $i) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compose a URL query parameter array for table sorting links.
|
* Composes a URL query parameter array for table sorting links.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* A URL query parameter array that consists of all components of the current
|
* A URL query parameter array that consists of all components of the current
|
||||||
@@ -190,10 +192,11 @@ function tablesort_get_query_parameters() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine the current sort criterion.
|
* Determines the current sort criterion.
|
||||||
*
|
*
|
||||||
* @param $headers
|
* @param $headers
|
||||||
* An array of column headers in the format described in theme_table().
|
* An array of column headers in the format described in theme_table().
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
* An associative array describing the criterion, containing the keys:
|
* An associative array describing the criterion, containing the keys:
|
||||||
* - "name": The localized title of the table column.
|
* - "name": The localized title of the table column.
|
||||||
@@ -226,10 +229,11 @@ function tablesort_get_order($headers) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine the current sort direction.
|
* Determines the current sort direction.
|
||||||
*
|
*
|
||||||
* @param $headers
|
* @param $headers
|
||||||
* An array of column headers in the format described in theme_table().
|
* An array of column headers in the format described in theme_table().
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
* The current sort direction ("asc" or "desc").
|
* The current sort direction ("asc" or "desc").
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ function _drupal_theme_access($theme) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the theme system by loading the theme.
|
* Initializes the theme system by loading the theme.
|
||||||
*/
|
*/
|
||||||
function drupal_theme_initialize() {
|
function drupal_theme_initialize() {
|
||||||
global $theme, $user, $theme_key;
|
global $theme, $user, $theme_key;
|
||||||
@@ -113,8 +113,9 @@ function drupal_theme_initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the theme system given already loaded information. This
|
* Initializes the theme system given already loaded information.
|
||||||
* function is useful to initialize a theme when no database is present.
|
*
|
||||||
|
* This function is useful to initialize a theme when no database is present.
|
||||||
*
|
*
|
||||||
* @param $theme
|
* @param $theme
|
||||||
* An object with the following information:
|
* An object with the following information:
|
||||||
@@ -235,7 +236,7 @@ function _drupal_theme_initialize($theme, $base_theme = array(), $registry_callb
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the theme registry.
|
* Gets the theme registry.
|
||||||
*
|
*
|
||||||
* @param $complete
|
* @param $complete
|
||||||
* Optional boolean to indicate whether to return the complete theme registry
|
* Optional boolean to indicate whether to return the complete theme registry
|
||||||
@@ -280,7 +281,7 @@ function theme_get_registry($complete = TRUE) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the callback that will be used by theme_get_registry() to fetch the registry.
|
* Sets the callback that will be used by theme_get_registry().
|
||||||
*
|
*
|
||||||
* @param $callback
|
* @param $callback
|
||||||
* The name of the callback function.
|
* The name of the callback function.
|
||||||
@@ -296,7 +297,7 @@ function _theme_registry_callback($callback = NULL, array $arguments = array())
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the theme_registry cache; if it doesn't exist, build it.
|
* Gets the theme_registry cache; if it doesn't exist, builds it.
|
||||||
*
|
*
|
||||||
* @param $theme
|
* @param $theme
|
||||||
* The loaded $theme object as returned by list_themes().
|
* The loaded $theme object as returned by list_themes().
|
||||||
@@ -336,16 +337,17 @@ function _theme_load_registry($theme, $base_theme = NULL, $theme_engine = NULL,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the theme_registry cache into the database.
|
* Writes the theme_registry cache into the database.
|
||||||
*/
|
*/
|
||||||
function _theme_save_registry($theme, $registry) {
|
function _theme_save_registry($theme, $registry) {
|
||||||
cache_set("theme_registry:$theme->name", $registry);
|
cache_set("theme_registry:$theme->name", $registry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Force the system to rebuild the theme registry; this should be called
|
* Forces the system to rebuild the theme registry.
|
||||||
* when modules are added to the system, or when a dynamic system needs
|
*
|
||||||
* to add more theme hooks.
|
* This function should be called when modules are added to the system, or when
|
||||||
|
* a dynamic system needs to add more theme hooks.
|
||||||
*/
|
*/
|
||||||
function drupal_theme_rebuild() {
|
function drupal_theme_rebuild() {
|
||||||
drupal_static_reset('theme_get_registry');
|
drupal_static_reset('theme_get_registry');
|
||||||
@@ -506,7 +508,7 @@ class ThemeRegistry Extends DrupalCacheArray {
|
|||||||
* themes/bartik.
|
* themes/bartik.
|
||||||
*
|
*
|
||||||
* @see theme()
|
* @see theme()
|
||||||
* @see _theme_process_registry()
|
* @see _theme_build_registry()
|
||||||
* @see hook_theme()
|
* @see hook_theme()
|
||||||
* @see list_themes()
|
* @see list_themes()
|
||||||
*/
|
*/
|
||||||
@@ -635,7 +637,8 @@ function _theme_process_registry(&$cache, $name, $type, $theme, $path) {
|
|||||||
$cache = $result + $cache;
|
$cache = $result + $cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let themes have variable processors even if they didn't register a template.
|
// Let themes have variable processors even if they didn't register a
|
||||||
|
// template.
|
||||||
if ($type == 'theme' || $type == 'base_theme') {
|
if ($type == 'theme' || $type == 'base_theme') {
|
||||||
foreach ($cache as $hook => $info) {
|
foreach ($cache as $hook => $info) {
|
||||||
// Check only if not registered by the theme or engine.
|
// Check only if not registered by the theme or engine.
|
||||||
@@ -662,7 +665,7 @@ function _theme_process_registry(&$cache, $name, $type, $theme, $path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build the theme registry cache.
|
* Builds the theme registry cache.
|
||||||
*
|
*
|
||||||
* @param $theme
|
* @param $theme
|
||||||
* The loaded $theme object as returned by list_themes().
|
* The loaded $theme object as returned by list_themes().
|
||||||
@@ -724,7 +727,7 @@ function _theme_build_registry($theme, $base_theme, $theme_engine) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a list of all currently available themes.
|
* Returns a list of all currently available themes.
|
||||||
*
|
*
|
||||||
* Retrieved from the database, if available and the site is not in maintenance
|
* Retrieved from the database, if available and the site is not in maintenance
|
||||||
* mode; otherwise compiled freshly from the filesystem.
|
* mode; otherwise compiled freshly from the filesystem.
|
||||||
@@ -766,7 +769,7 @@ function _theme_build_registry($theme, $base_theme, $theme_engine) {
|
|||||||
* their base theme), direct sub-themes of sub-themes, etc. The keys are
|
* their base theme), direct sub-themes of sub-themes, etc. The keys are
|
||||||
* the themes' machine names, and the values are the themes' human-readable
|
* the themes' machine names, and the values are the themes' human-readable
|
||||||
* names. This element is not set if there are no themes on the system that
|
* names. This element is not set if there are no themes on the system that
|
||||||
* declare this theme as their base theme.
|
* declare this theme as their base theme.
|
||||||
*/
|
*/
|
||||||
function list_themes($refresh = FALSE) {
|
function list_themes($refresh = FALSE) {
|
||||||
$list = &drupal_static(__FUNCTION__, array());
|
$list = &drupal_static(__FUNCTION__, array());
|
||||||
@@ -866,11 +869,18 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) {
|
|||||||
/**
|
/**
|
||||||
* Generates themed output.
|
* Generates themed output.
|
||||||
*
|
*
|
||||||
* All requests for themed output must go through this function. It examines
|
* All requests for themed output must go through this function (however,
|
||||||
* the request and routes it to the appropriate
|
* calling the theme() function directly is strongly discouraged - see next
|
||||||
|
* paragraph). It examines the request and routes it to the appropriate
|
||||||
* @link themeable theme function or template @endlink, by checking the theme
|
* @link themeable theme function or template @endlink, by checking the theme
|
||||||
* registry.
|
* registry.
|
||||||
*
|
*
|
||||||
|
* Avoid calling this function directly. It is preferable to replace direct
|
||||||
|
* calls to the theme() function with calls to drupal_render() by passing a
|
||||||
|
* render array with a #theme key to drupal_render(), which in turn calls
|
||||||
|
* theme().
|
||||||
|
*
|
||||||
|
* @section sec_theme_hooks Theme Hooks
|
||||||
* Most commonly, the first argument to this function is the name of the theme
|
* Most commonly, the first argument to this function is the name of the theme
|
||||||
* hook. For instance, to theme a taxonomy term, the theme hook name is
|
* hook. For instance, to theme a taxonomy term, the theme hook name is
|
||||||
* 'taxonomy_term'. Modules register theme hooks within a hook_theme()
|
* 'taxonomy_term'. Modules register theme hooks within a hook_theme()
|
||||||
@@ -882,6 +892,7 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) {
|
|||||||
* underscores changed to hyphens, so for the 'taxonomy_term' theme hook, the
|
* underscores changed to hyphens, so for the 'taxonomy_term' theme hook, the
|
||||||
* default template is 'taxonomy-term.tpl.php'.
|
* default template is 'taxonomy-term.tpl.php'.
|
||||||
*
|
*
|
||||||
|
* @subsection sub_overriding_theme_hooks Overriding Theme Hooks
|
||||||
* Themes may also register new theme hooks within a hook_theme()
|
* Themes may also register new theme hooks within a hook_theme()
|
||||||
* implementation, but it is more common for themes to override default
|
* implementation, but it is more common for themes to override default
|
||||||
* implementations provided by modules than to register entirely new theme
|
* implementations provided by modules than to register entirely new theme
|
||||||
@@ -894,21 +905,22 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) {
|
|||||||
* rendering engine, it overrides the default implementation of the 'page' theme
|
* rendering engine, it overrides the default implementation of the 'page' theme
|
||||||
* hook by containing a 'page.tpl.php' file within its folder structure).
|
* hook by containing a 'page.tpl.php' file within its folder structure).
|
||||||
*
|
*
|
||||||
|
* @subsection sub_preprocess_templates Preprocessing for Template Files
|
||||||
* If the implementation is a template file, several functions are called
|
* If the implementation is a template file, several functions are called
|
||||||
* before the template file is invoked, to modify the $variables array. These
|
* before the template file is invoked, to modify the $variables array. These
|
||||||
* fall into the "preprocessing" phase and the "processing" phase, and are
|
* fall into the "preprocessing" phase and the "processing" phase, and are
|
||||||
* executed (if they exist), in the following order (note that in the following
|
* executed (if they exist), in the following order (note that in the following
|
||||||
* list, HOOK indicates the theme hook name, MODULE indicates a module name,
|
* list, HOOK indicates the theme hook name, MODULE indicates a module name,
|
||||||
* THEME indicates a theme name, and ENGINE indicates a theme engine name):
|
* THEME indicates a theme name, and ENGINE indicates a theme engine name):
|
||||||
* - template_preprocess(&$variables, $hook): Creates a default set of variables
|
* - template_preprocess(&$variables, $hook): Creates a default set of
|
||||||
* for all theme hooks with template implementations.
|
* variables for all theme hooks with template implementations.
|
||||||
* - template_preprocess_HOOK(&$variables): Should be implemented by the module
|
* - template_preprocess_HOOK(&$variables): Should be implemented by the module
|
||||||
* that registers the theme hook, to set up default variables.
|
* that registers the theme hook, to set up default variables.
|
||||||
* - MODULE_preprocess(&$variables, $hook): hook_preprocess() is invoked on all
|
* - MODULE_preprocess(&$variables, $hook): hook_preprocess() is invoked on all
|
||||||
* implementing modules.
|
* implementing modules.
|
||||||
* - MODULE_preprocess_HOOK(&$variables): hook_preprocess_HOOK() is invoked on
|
* - MODULE_preprocess_HOOK(&$variables): hook_preprocess_HOOK() is invoked on
|
||||||
* all implementing modules, so that modules that didn't define the theme hook
|
* all implementing modules, so that modules that didn't define the theme
|
||||||
* can alter the variables.
|
* hook can alter the variables.
|
||||||
* - ENGINE_engine_preprocess(&$variables, $hook): Allows the theme engine to
|
* - ENGINE_engine_preprocess(&$variables, $hook): Allows the theme engine to
|
||||||
* set necessary variables for all theme hooks with template implementations.
|
* set necessary variables for all theme hooks with template implementations.
|
||||||
* - ENGINE_engine_preprocess_HOOK(&$variables): Allows the theme engine to set
|
* - ENGINE_engine_preprocess_HOOK(&$variables): Allows the theme engine to set
|
||||||
@@ -942,12 +954,14 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) {
|
|||||||
* - THEME_process_HOOK(&$variables): Allows the theme to process the
|
* - THEME_process_HOOK(&$variables): Allows the theme to process the
|
||||||
* variables specific to the theme hook.
|
* variables specific to the theme hook.
|
||||||
*
|
*
|
||||||
|
* @subsection sub_preprocess_theme_funcs Preprocessing for Theme Functions
|
||||||
* If the implementation is a function, only the theme-hook-specific preprocess
|
* If the implementation is a function, only the theme-hook-specific preprocess
|
||||||
* and process functions (the ones ending in _HOOK) are called from the
|
* and process functions (the ones ending in _HOOK) are called from the
|
||||||
* list above. This is because theme hooks with function implementations
|
* list above. This is because theme hooks with function implementations
|
||||||
* need to be fast, and calling the non-theme-hook-specific preprocess and
|
* need to be fast, and calling the non-theme-hook-specific preprocess and
|
||||||
* process functions for them would incur a noticeable performance penalty.
|
* process functions for them would incur a noticeable performance penalty.
|
||||||
*
|
*
|
||||||
|
* @subsection sub_alternate_suggestions Suggesting Alternate Hooks
|
||||||
* There are two special variables that these preprocess and process functions
|
* There are two special variables that these preprocess and process functions
|
||||||
* can set: 'theme_hook_suggestion' and 'theme_hook_suggestions'. These will be
|
* can set: 'theme_hook_suggestion' and 'theme_hook_suggestions'. These will be
|
||||||
* merged together to form a list of 'suggested' alternate theme hooks to use,
|
* merged together to form a list of 'suggested' alternate theme hooks to use,
|
||||||
@@ -963,10 +977,10 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) {
|
|||||||
* @param $hook
|
* @param $hook
|
||||||
* The name of the theme hook to call. If the name contains a
|
* The name of the theme hook to call. If the name contains a
|
||||||
* double-underscore ('__') and there isn't an implementation for the full
|
* double-underscore ('__') and there isn't an implementation for the full
|
||||||
* name, the part before the '__' is checked. This allows a fallback to a more
|
* name, the part before the '__' is checked. This allows a fallback to a
|
||||||
* generic implementation. For example, if theme('links__node', ...) is
|
* more generic implementation. For example, if theme('links__node', ...) is
|
||||||
* called, but there is no implementation of that theme hook, then the 'links'
|
* called, but there is no implementation of that theme hook, then the
|
||||||
* implementation is used. This process is iterative, so if
|
* 'links' implementation is used. This process is iterative, so if
|
||||||
* theme('links__contextual__node', ...) is called, theme() checks for the
|
* theme('links__contextual__node', ...) is called, theme() checks for the
|
||||||
* following implementations, and uses the first one that exists:
|
* following implementations, and uses the first one that exists:
|
||||||
* - links__contextual__node
|
* - links__contextual__node
|
||||||
@@ -989,6 +1003,7 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) {
|
|||||||
* @return
|
* @return
|
||||||
* An HTML string representing the themed output.
|
* An HTML string representing the themed output.
|
||||||
*
|
*
|
||||||
|
* @see drupal_render()
|
||||||
* @see themeable
|
* @see themeable
|
||||||
* @see hook_theme()
|
* @see hook_theme()
|
||||||
* @see template_preprocess()
|
* @see template_preprocess()
|
||||||
@@ -1030,7 +1045,7 @@ function theme($hook, $variables = array()) {
|
|||||||
// Only log a message when not trying theme suggestions ($hook being an
|
// Only log a message when not trying theme suggestions ($hook being an
|
||||||
// array).
|
// array).
|
||||||
if (!isset($candidate)) {
|
if (!isset($candidate)) {
|
||||||
watchdog('theme', 'Theme key "@key" not found.', array('@key' => $hook), WATCHDOG_WARNING);
|
watchdog('theme', 'Theme hook %hook not found.', array('%hook' => $hook), WATCHDOG_WARNING);
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@@ -1042,7 +1057,8 @@ function theme($hook, $variables = array()) {
|
|||||||
// point path_to_theme() to the currently used theme path:
|
// point path_to_theme() to the currently used theme path:
|
||||||
$theme_path = $info['theme path'];
|
$theme_path = $info['theme path'];
|
||||||
|
|
||||||
// Include a file if the theme function or variable processor is held elsewhere.
|
// Include a file if the theme function or variable processor is held
|
||||||
|
// elsewhere.
|
||||||
if (!empty($info['includes'])) {
|
if (!empty($info['includes'])) {
|
||||||
foreach ($info['includes'] as $include_file) {
|
foreach ($info['includes'] as $include_file) {
|
||||||
include_once DRUPAL_ROOT . '/' . $include_file;
|
include_once DRUPAL_ROOT . '/' . $include_file;
|
||||||
@@ -1191,14 +1207,14 @@ function theme($hook, $variables = array()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the path to the current themed element.
|
* Returns the path to the current themed element.
|
||||||
*
|
*
|
||||||
* It can point to the active theme or the module handling a themed implementation.
|
* It can point to the active theme or the module handling a themed
|
||||||
* For example, when invoked within the scope of a theming call it will depend
|
* implementation. For example, when invoked within the scope of a theming call
|
||||||
* on where the theming function is handled. If implemented from a module, it
|
* it will depend on where the theming function is handled. If implemented from
|
||||||
* will point to the module. If implemented from the active theme, it will point
|
* a module, it will point to the module. If implemented from the active theme,
|
||||||
* to the active theme. When called outside the scope of a theming call, it will
|
* it will point to the active theme. When called outside the scope of a
|
||||||
* always point to the active theme.
|
* theming call, it will always point to the active theme.
|
||||||
*/
|
*/
|
||||||
function path_to_theme() {
|
function path_to_theme() {
|
||||||
global $theme_path;
|
global $theme_path;
|
||||||
@@ -1211,7 +1227,7 @@ function path_to_theme() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow themes and/or theme engines to easily discover overridden theme functions.
|
* Allows themes and/or theme engines to discover overridden theme functions.
|
||||||
*
|
*
|
||||||
* @param $cache
|
* @param $cache
|
||||||
* The existing cache of theme hooks to test against.
|
* The existing cache of theme hooks to test against.
|
||||||
@@ -1268,7 +1284,7 @@ function drupal_find_theme_functions($cache, $prefixes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow themes and/or theme engines to easily discover overridden templates.
|
* Allows themes and/or theme engines to easily discover overridden templates.
|
||||||
*
|
*
|
||||||
* @param $cache
|
* @param $cache
|
||||||
* The existing cache of theme hooks to test against.
|
* The existing cache of theme hooks to test against.
|
||||||
@@ -1345,7 +1361,8 @@ function drupal_find_theme_templates($cache, $extension, $path) {
|
|||||||
if ($matches) {
|
if ($matches) {
|
||||||
foreach ($matches as $match) {
|
foreach ($matches as $match) {
|
||||||
$file = substr($match, 0, strpos($match, '.'));
|
$file = substr($match, 0, strpos($match, '.'));
|
||||||
// Put the underscores back in for the hook name and register this pattern.
|
// Put the underscores back in for the hook name and register this
|
||||||
|
// pattern.
|
||||||
$arg_name = isset($info['variables']) ? 'variables' : 'render element';
|
$arg_name = isset($info['variables']) ? 'variables' : 'render element';
|
||||||
$implementations[strtr($file, '-', '_')] = array(
|
$implementations[strtr($file, '-', '_')] = array(
|
||||||
'template' => $file,
|
'template' => $file,
|
||||||
@@ -1361,7 +1378,7 @@ function drupal_find_theme_templates($cache, $extension, $path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a setting for the current theme or for a given theme.
|
* Retrieves a setting for the current theme or for a given theme.
|
||||||
*
|
*
|
||||||
* The final setting is obtained from the last value found in the following
|
* The final setting is obtained from the last value found in the following
|
||||||
* sources:
|
* sources:
|
||||||
@@ -1479,7 +1496,7 @@ function theme_get_setting($setting_name, $theme = NULL) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a system default template, which is essentially a PHP template.
|
* Renders a system default template, which is essentially a PHP template.
|
||||||
*
|
*
|
||||||
* @param $template_file
|
* @param $template_file
|
||||||
* The filename of the template to render.
|
* The filename of the template to render.
|
||||||
@@ -1490,14 +1507,21 @@ function theme_get_setting($setting_name, $theme = NULL) {
|
|||||||
* The output generated by the template.
|
* The output generated by the template.
|
||||||
*/
|
*/
|
||||||
function theme_render_template($template_file, $variables) {
|
function theme_render_template($template_file, $variables) {
|
||||||
extract($variables, EXTR_SKIP); // Extract the variables to a local namespace
|
// Extract the variables to a local namespace
|
||||||
ob_start(); // Start output buffering
|
extract($variables, EXTR_SKIP);
|
||||||
include DRUPAL_ROOT . '/' . $template_file; // Include the template file
|
|
||||||
return ob_get_clean(); // End buffering and return its contents
|
// Start output buffering
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
// Include the template file
|
||||||
|
include DRUPAL_ROOT . '/' . $template_file;
|
||||||
|
|
||||||
|
// End buffering and return its contents
|
||||||
|
return ob_get_clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable a given list of themes.
|
* Enables a given list of themes.
|
||||||
*
|
*
|
||||||
* @param $theme_list
|
* @param $theme_list
|
||||||
* An array of theme names.
|
* An array of theme names.
|
||||||
@@ -1522,7 +1546,7 @@ function theme_enable($theme_list) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable a given list of themes.
|
* Disables a given list of themes.
|
||||||
*
|
*
|
||||||
* @param $theme_list
|
* @param $theme_list
|
||||||
* An array of theme names.
|
* An array of theme names.
|
||||||
@@ -1608,13 +1632,13 @@ function theme_status_messages($variables) {
|
|||||||
* theme('link') for rendering the anchor tag.
|
* theme('link') for rendering the anchor tag.
|
||||||
*
|
*
|
||||||
* To optimize performance for sites that don't need custom theming of links,
|
* To optimize performance for sites that don't need custom theming of links,
|
||||||
* the l() function includes an inline copy of this function, and uses that copy
|
* the l() function includes an inline copy of this function, and uses that
|
||||||
* if none of the enabled modules or the active theme implement any preprocess
|
* copy if none of the enabled modules or the active theme implement any
|
||||||
* or process functions or override this theme implementation.
|
* preprocess or process functions or override this theme implementation.
|
||||||
*
|
*
|
||||||
* @param $variables
|
* @param $variables
|
||||||
* An associative array containing the keys 'text', 'path', and 'options'. See
|
* An associative array containing the keys 'text', 'path', and 'options'.
|
||||||
* the l() function for information about these variables.
|
* See the l() function for information about these variables.
|
||||||
*
|
*
|
||||||
* @see l()
|
* @see l()
|
||||||
*/
|
*/
|
||||||
@@ -1635,15 +1659,16 @@ function theme_link($variables) {
|
|||||||
* item in the links list.
|
* item in the links list.
|
||||||
* - html: (optional) Whether or not 'title' is HTML. If set, the title
|
* - html: (optional) Whether or not 'title' is HTML. If set, the title
|
||||||
* will not be passed through check_plain().
|
* will not be passed through check_plain().
|
||||||
* - attributes: (optional) Attributes for the anchor, or for the <span> tag
|
* - attributes: (optional) Attributes for the anchor, or for the <span>
|
||||||
* used in its place if no 'href' is supplied. If element 'class' is
|
* tag used in its place if no 'href' is supplied. If element 'class' is
|
||||||
* included, it must be an array of one or more class names.
|
* included, it must be an array of one or more class names.
|
||||||
* If the 'href' element is supplied, the entire link array is passed to l()
|
* If the 'href' element is supplied, the entire link array is passed to
|
||||||
* as its $options parameter.
|
* l() as its $options parameter.
|
||||||
* - attributes: A keyed array of attributes for the UL containing the
|
* - attributes: A keyed array of attributes for the UL containing the
|
||||||
* list of links.
|
* list of links.
|
||||||
* - heading: (optional) A heading to precede the links. May be an associative
|
* - heading: (optional) A heading to precede the links. May be an
|
||||||
* array or a string. If it's an array, it can have the following elements:
|
* associative array or a string. If it's an array, it can have the
|
||||||
|
* following elements:
|
||||||
* - text: The heading text.
|
* - text: The heading text.
|
||||||
* - level: The heading level (e.g. 'h2', 'h3').
|
* - level: The heading level (e.g. 'h2', 'h3').
|
||||||
* - class: (optional) An array of the CSS classes for the heading.
|
* - class: (optional) An array of the CSS classes for the heading.
|
||||||
@@ -1747,8 +1772,8 @@ function theme_links($variables) {
|
|||||||
* attribute to be omitted in some cases. Therefore, this variable defaults
|
* attribute to be omitted in some cases. Therefore, this variable defaults
|
||||||
* to an empty string, but can be set to NULL for the attribute to be
|
* to an empty string, but can be set to NULL for the attribute to be
|
||||||
* omitted. Usually, neither omission nor an empty string satisfies
|
* omitted. Usually, neither omission nor an empty string satisfies
|
||||||
* accessibility requirements, so it is strongly encouraged for code calling
|
* accessibility requirements, so it is strongly encouraged for code
|
||||||
* theme('image') to pass a meaningful value for this variable.
|
* calling theme('image') to pass a meaningful value for this variable.
|
||||||
* - http://www.w3.org/TR/REC-html40/struct/objects.html#h-13.8
|
* - http://www.w3.org/TR/REC-html40/struct/objects.html#h-13.8
|
||||||
* - http://www.w3.org/TR/xhtml1/dtds.html
|
* - http://www.w3.org/TR/xhtml1/dtds.html
|
||||||
* - http://dev.w3.org/html5/spec/Overview.html#alt
|
* - http://dev.w3.org/html5/spec/Overview.html#alt
|
||||||
@@ -1801,7 +1826,9 @@ function theme_breadcrumb($variables) {
|
|||||||
* - "data": The localized title of the table column.
|
* - "data": The localized title of the table column.
|
||||||
* - "field": The database field represented in the table column (required
|
* - "field": The database field represented in the table column (required
|
||||||
* if user is to be able to sort on this column).
|
* if user is to be able to sort on this column).
|
||||||
* - "sort": A default sort order for this column ("asc" or "desc").
|
* - "sort": A default sort order for this column ("asc" or "desc"). Only
|
||||||
|
* one column should be given a default sort order because table sorting
|
||||||
|
* only applies to one column at a time.
|
||||||
* - Any HTML attributes, such as "colspan", to apply to the column header
|
* - Any HTML attributes, such as "colspan", to apply to the column header
|
||||||
* cell.
|
* cell.
|
||||||
* - rows: An array of table rows. Every row is an array of cells, or an
|
* - rows: An array of table rows. Every row is an array of cells, or an
|
||||||
@@ -1960,25 +1987,24 @@ function theme_table($variables) {
|
|||||||
$flip = array('even' => 'odd', 'odd' => 'even');
|
$flip = array('even' => 'odd', 'odd' => 'even');
|
||||||
$class = 'even';
|
$class = 'even';
|
||||||
foreach ($rows as $number => $row) {
|
foreach ($rows as $number => $row) {
|
||||||
$attributes = array();
|
|
||||||
|
|
||||||
// Check if we're dealing with a simple or complex row
|
// Check if we're dealing with a simple or complex row
|
||||||
if (isset($row['data'])) {
|
if (isset($row['data'])) {
|
||||||
foreach ($row as $key => $value) {
|
$cells = $row['data'];
|
||||||
if ($key == 'data') {
|
$no_striping = isset($row['no_striping']) ? $row['no_striping'] : FALSE;
|
||||||
$cells = $value;
|
|
||||||
}
|
// Set the attributes array and exclude 'data' and 'no_striping'.
|
||||||
else {
|
$attributes = $row;
|
||||||
$attributes[$key] = $value;
|
unset($attributes['data']);
|
||||||
}
|
unset($attributes['no_striping']);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$cells = $row;
|
$cells = $row;
|
||||||
|
$attributes = array();
|
||||||
|
$no_striping = FALSE;
|
||||||
}
|
}
|
||||||
if (count($cells)) {
|
if (count($cells)) {
|
||||||
// Add odd/even class
|
// Add odd/even class
|
||||||
if (empty($row['no_striping'])) {
|
if (!$no_striping) {
|
||||||
$class = $flip[$class];
|
$class = $flip[$class];
|
||||||
$attributes['class'][] = $class;
|
$attributes['class'][] = $class;
|
||||||
}
|
}
|
||||||
@@ -2005,7 +2031,8 @@ function theme_table($variables) {
|
|||||||
*
|
*
|
||||||
* @param $variables
|
* @param $variables
|
||||||
* An associative array containing:
|
* An associative array containing:
|
||||||
* - style: Set to either 'asc' or 'desc', this determines which icon to show.
|
* - style: Set to either 'asc' or 'desc', this determines which icon to
|
||||||
|
* show.
|
||||||
*/
|
*/
|
||||||
function theme_tablesort_indicator($variables) {
|
function theme_tablesort_indicator($variables) {
|
||||||
if ($variables['style'] == "asc") {
|
if ($variables['style'] == "asc") {
|
||||||
@@ -2148,7 +2175,8 @@ function theme_feed_icon($variables) {
|
|||||||
* - script: To load JavaScript.
|
* - script: To load JavaScript.
|
||||||
* - #attributes: (optional) An array of HTML attributes to apply to the
|
* - #attributes: (optional) An array of HTML attributes to apply to the
|
||||||
* tag.
|
* tag.
|
||||||
* - #value: (optional) A string containing tag content, such as inline CSS.
|
* - #value: (optional) A string containing tag content, such as inline
|
||||||
|
* CSS.
|
||||||
* - #value_prefix: (optional) A string to prepend to #value, e.g. a CDATA
|
* - #value_prefix: (optional) A string to prepend to #value, e.g. a CDATA
|
||||||
* wrapper prefix.
|
* wrapper prefix.
|
||||||
* - #value_suffix: (optional) A string to append to #value, e.g. a CDATA
|
* - #value_suffix: (optional) A string to append to #value, e.g. a CDATA
|
||||||
@@ -2316,8 +2344,9 @@ function template_preprocess(&$variables, $hook) {
|
|||||||
global $user;
|
global $user;
|
||||||
static $count = array();
|
static $count = array();
|
||||||
|
|
||||||
// Track run count for each hook to provide zebra striping.
|
// Track run count for each hook to provide zebra striping. See
|
||||||
// See "template_preprocess_block()" which provides the same feature specific to blocks.
|
// "template_preprocess_block()" which provides the same feature specific to
|
||||||
|
// blocks.
|
||||||
$count[$hook] = isset($count[$hook]) && is_int($count[$hook]) ? $count[$hook] : 1;
|
$count[$hook] = isset($count[$hook]) && is_int($count[$hook]) ? $count[$hook] : 1;
|
||||||
$variables['zebra'] = ($count[$hook] % 2) ? 'odd' : 'even';
|
$variables['zebra'] = ($count[$hook] % 2) ? 'odd' : 'even';
|
||||||
$variables['id'] = $count[$hook]++;
|
$variables['id'] = $count[$hook]++;
|
||||||
@@ -2677,13 +2706,13 @@ function theme_get_suggestions($args, $base, $delimiter = '__') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The variables array generated here is a mirror of template_preprocess_page().
|
* Process variables for maintenance-page.tpl.php.
|
||||||
* This preprocessor will run its course when theme_maintenance_page() is
|
|
||||||
* invoked.
|
|
||||||
*
|
*
|
||||||
* An alternate template file of "maintenance-page--offline.tpl.php" can be
|
* The variables array generated here is a mirror of
|
||||||
* used when the database is offline to hide errors and completely replace the
|
* template_preprocess_page(). This preprocessor will run its course when
|
||||||
* content.
|
* theme_maintenance_page() is invoked. An alternate template file of
|
||||||
|
* maintenance-page--offline.tpl.php can be used when the database is offline to
|
||||||
|
* hide errors and completely replace the content.
|
||||||
*
|
*
|
||||||
* The $variables array contains the following arguments:
|
* The $variables array contains the following arguments:
|
||||||
* - $content
|
* - $content
|
||||||
@@ -2777,10 +2806,13 @@ function template_preprocess_maintenance_page(&$variables) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Theme process function for theme_maintenance_field().
|
||||||
|
*
|
||||||
* The variables array generated here is a mirror of template_process_html().
|
* The variables array generated here is a mirror of template_process_html().
|
||||||
* This processor will run its course when theme_maintenance_page() is invoked.
|
* This processor will run its course when theme_maintenance_page() is invoked.
|
||||||
*
|
*
|
||||||
* @see maintenance-page.tpl.php
|
* @see maintenance-page.tpl.php
|
||||||
|
* @see template_process_html()
|
||||||
*/
|
*/
|
||||||
function template_process_maintenance_page(&$variables) {
|
function template_process_maintenance_page(&$variables) {
|
||||||
$variables['head'] = drupal_get_html_head();
|
$variables['head'] = drupal_get_html_head();
|
||||||
@@ -2792,7 +2824,7 @@ function template_process_maintenance_page(&$variables) {
|
|||||||
/**
|
/**
|
||||||
* Preprocess variables for region.tpl.php
|
* Preprocess variables for region.tpl.php
|
||||||
*
|
*
|
||||||
* Prepare the values passed to the theme_region function to be passed into a
|
* Prepares the values passed to the theme_region function to be passed into a
|
||||||
* pluggable template engine. Uses the region name to generate a template file
|
* pluggable template engine. Uses the region name to generate a template file
|
||||||
* suggestions. If none are found, the default region.tpl.php is used.
|
* suggestions. If none are found, the default region.tpl.php is used.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -10,9 +10,9 @@
|
|||||||
*
|
*
|
||||||
* Used for site installs, updates and when the site is in maintenance mode.
|
* Used for site installs, updates and when the site is in maintenance mode.
|
||||||
* It also applies when the database is unavailable or bootstrap was not
|
* It also applies when the database is unavailable or bootstrap was not
|
||||||
* complete. Seven is always used for the initial install and update operations.
|
* complete. Seven is always used for the initial install and update
|
||||||
* In other cases, Bartik is used, but this can be overridden by setting a
|
* operations. In other cases, Bartik is used, but this can be overridden by
|
||||||
* "maintenance_theme" key in the $conf variable in settings.php.
|
* setting a "maintenance_theme" key in the $conf variable in settings.php.
|
||||||
*/
|
*/
|
||||||
function _drupal_maintenance_theme() {
|
function _drupal_maintenance_theme() {
|
||||||
global $theme, $theme_key, $conf;
|
global $theme, $theme_key, $conf;
|
||||||
@@ -85,7 +85,7 @@ function _drupal_maintenance_theme() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This builds the registry when the site needs to bypass any database calls.
|
* Builds the registry when the site needs to bypass any database calls.
|
||||||
*/
|
*/
|
||||||
function _theme_load_offline_registry($theme, $base_theme = NULL, $theme_engine = NULL) {
|
function _theme_load_offline_registry($theme, $base_theme = NULL, $theme_engine = NULL) {
|
||||||
return _theme_build_registry($theme, $base_theme, $theme_engine);
|
return _theme_build_registry($theme, $base_theme, $theme_engine);
|
||||||
@@ -160,7 +160,7 @@ function theme_update_page($variables) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns HTML for a report of the results from an operation run via authorize.php.
|
* Returns HTML for a results report of an operation run by authorize.php.
|
||||||
*
|
*
|
||||||
* @param $variables
|
* @param $variables
|
||||||
* An associative array containing:
|
* An associative array containing:
|
||||||
|
|||||||
@@ -113,13 +113,13 @@ function token_replace($text, array $data = array(), array $options = array()) {
|
|||||||
*/
|
*/
|
||||||
function token_scan($text) {
|
function token_scan($text) {
|
||||||
// Matches tokens with the following pattern: [$type:$name]
|
// Matches tokens with the following pattern: [$type:$name]
|
||||||
// $type and $name may not contain [ ] or whitespace characters.
|
// $type and $name may not contain [ ] characters.
|
||||||
// $type may not contain : characters, but $name may.
|
// $type may not contain : or whitespace characters, but $name may.
|
||||||
preg_match_all('/
|
preg_match_all('/
|
||||||
\[ # [ - pattern start
|
\[ # [ - pattern start
|
||||||
([^\s\[\]:]*) # match $type not containing whitespace : [ or ]
|
([^\s\[\]:]*) # match $type not containing whitespace : [ or ]
|
||||||
: # : - separator
|
: # : - separator
|
||||||
([^\s\[\]]*) # match $name not containing whitespace [ or ]
|
([^\[\]]*) # match $name not containing [ or ]
|
||||||
\] # ] - pattern end
|
\] # ] - pattern end
|
||||||
/x', $text, $matches);
|
/x', $text, $matches);
|
||||||
|
|
||||||
@@ -190,10 +190,10 @@ function token_generate($type, array $tokens, array $data = array(), array $opti
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a list of tokens, returns those that begin with a specific prefix.
|
* Returns a list of tokens that begin with a specific prefix.
|
||||||
*
|
*
|
||||||
* Used to extract a group of 'chained' tokens (such as [node:author:name]) from
|
* Used to extract a group of 'chained' tokens (such as [node:author:name])
|
||||||
* the full list of tokens found in text. For example:
|
* from the full list of tokens found in text. For example:
|
||||||
* @code
|
* @code
|
||||||
* $data = array(
|
* $data = array(
|
||||||
* 'author:name' => '[node:author:name]',
|
* 'author:name' => '[node:author:name]',
|
||||||
@@ -230,8 +230,10 @@ function token_find_with_prefix(array $tokens, $prefix, $delimiter = ':') {
|
|||||||
/**
|
/**
|
||||||
* Returns metadata describing supported tokens.
|
* Returns metadata describing supported tokens.
|
||||||
*
|
*
|
||||||
* The metadata array contains token type, name, and description data as well as
|
* The metadata array contains token type, name, and description data as well
|
||||||
* an optional pointer indicating that the token chains to another set of tokens.
|
* as an optional pointer indicating that the token chains to another set of
|
||||||
|
* tokens.
|
||||||
|
*
|
||||||
* For example:
|
* For example:
|
||||||
* @code
|
* @code
|
||||||
* $data['types']['node'] = array(
|
* $data['types']['node'] = array(
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Provides Unicode-related conversions and operations.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates an error during check for PHP unicode support.
|
* Indicates an error during check for PHP unicode support.
|
||||||
*/
|
*/
|
||||||
@@ -19,8 +24,6 @@ define('UNICODE_MULTIBYTE', 1);
|
|||||||
/**
|
/**
|
||||||
* Matches Unicode characters that are word boundaries.
|
* Matches Unicode characters that are word boundaries.
|
||||||
*
|
*
|
||||||
* @see http://unicode.org/glossary
|
|
||||||
*
|
|
||||||
* Characters with the following General_category (gc) property values are used
|
* Characters with the following General_category (gc) property values are used
|
||||||
* as word boundaries. While this does not fully conform to the Word Boundaries
|
* as word boundaries. While this does not fully conform to the Word Boundaries
|
||||||
* algorithm described in http://unicode.org/reports/tr29, as PCRE does not
|
* algorithm described in http://unicode.org/reports/tr29, as PCRE does not
|
||||||
@@ -39,6 +42,8 @@ define('UNICODE_MULTIBYTE', 1);
|
|||||||
* Note that the PCRE property matcher is not used because we wanted to be
|
* Note that the PCRE property matcher is not used because we wanted to be
|
||||||
* compatible with Unicode 5.2.0 regardless of the PCRE version used (and any
|
* compatible with Unicode 5.2.0 regardless of the PCRE version used (and any
|
||||||
* bugs in PCRE property tables).
|
* bugs in PCRE property tables).
|
||||||
|
*
|
||||||
|
* @see http://unicode.org/glossary
|
||||||
*/
|
*/
|
||||||
define('PREG_CLASS_UNICODE_WORD_BOUNDARY',
|
define('PREG_CLASS_UNICODE_WORD_BOUNDARY',
|
||||||
'\x{0}-\x{2F}\x{3A}-\x{40}\x{5B}-\x{60}\x{7B}-\x{A9}\x{AB}-\x{B1}\x{B4}' .
|
'\x{0}-\x{2F}\x{3A}-\x{40}\x{5B}-\x{60}\x{7B}-\x{A9}\x{AB}-\x{B1}\x{B4}' .
|
||||||
@@ -125,7 +130,7 @@ function _unicode_check() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return Unicode library status and errors.
|
* Returns Unicode library status and errors.
|
||||||
*/
|
*/
|
||||||
function unicode_requirements() {
|
function unicode_requirements() {
|
||||||
// Ensure translations don't break during installation.
|
// Ensure translations don't break during installation.
|
||||||
@@ -157,14 +162,14 @@ function unicode_requirements() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare a new XML parser.
|
* Prepares a new XML parser.
|
||||||
*
|
*
|
||||||
* This is a wrapper around xml_parser_create() which extracts the encoding from
|
* This is a wrapper around xml_parser_create() which extracts the encoding
|
||||||
* the XML data first and sets the output encoding to UTF-8. This function should
|
* from the XML data first and sets the output encoding to UTF-8. This function
|
||||||
* be used instead of xml_parser_create(), because PHP 4's XML parser doesn't
|
* should be used instead of xml_parser_create(), because PHP 4's XML parser
|
||||||
* check the input encoding itself. "Starting from PHP 5, the input encoding is
|
* doesn't check the input encoding itself. "Starting from PHP 5, the input
|
||||||
* automatically detected, so that the encoding parameter specifies only the
|
* encoding is automatically detected, so that the encoding parameter specifies
|
||||||
* output encoding."
|
* only the output encoding."
|
||||||
*
|
*
|
||||||
* This is also where unsupported encodings will be converted. Callers should
|
* This is also where unsupported encodings will be converted. Callers should
|
||||||
* take this into account: $data might have been changed after the call.
|
* take this into account: $data might have been changed after the call.
|
||||||
@@ -213,7 +218,7 @@ function drupal_xml_parser_create(&$data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert data to UTF-8
|
* Converts data to UTF-8.
|
||||||
*
|
*
|
||||||
* Requires the iconv, GNU recode or mbstring PHP extension.
|
* Requires the iconv, GNU recode or mbstring PHP extension.
|
||||||
*
|
*
|
||||||
@@ -244,15 +249,15 @@ function drupal_convert_to_utf8($data, $encoding) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Truncate a UTF-8-encoded string safely to a number of bytes.
|
* Truncates a UTF-8-encoded string safely to a number of bytes.
|
||||||
*
|
*
|
||||||
* If the end position is in the middle of a UTF-8 sequence, it scans backwards
|
* If the end position is in the middle of a UTF-8 sequence, it scans backwards
|
||||||
* until the beginning of the byte sequence.
|
* until the beginning of the byte sequence.
|
||||||
*
|
*
|
||||||
* Use this function whenever you want to chop off a string at an unsure
|
* Use this function whenever you want to chop off a string at an unsure
|
||||||
* location. On the other hand, if you're sure that you're splitting on a
|
* location. On the other hand, if you're sure that you're splitting on a
|
||||||
* character boundary (e.g. after using strpos() or similar), you can safely use
|
* character boundary (e.g. after using strpos() or similar), you can safely
|
||||||
* substr() instead.
|
* use substr() instead.
|
||||||
*
|
*
|
||||||
* @param $string
|
* @param $string
|
||||||
* The string to truncate.
|
* The string to truncate.
|
||||||
@@ -306,7 +311,7 @@ function drupal_truncate_bytes($string, $len) {
|
|||||||
* boundaries, giving you "See myverylongurl..." (assuming you had set
|
* boundaries, giving you "See myverylongurl..." (assuming you had set
|
||||||
* $add_ellipses to TRUE).
|
* $add_ellipses to TRUE).
|
||||||
*
|
*
|
||||||
* @return
|
* @return string
|
||||||
* The truncated string.
|
* The truncated string.
|
||||||
*/
|
*/
|
||||||
function truncate_utf8($string, $max_length, $wordsafe = FALSE, $add_ellipsis = FALSE, $min_wordsafe_length = 1) {
|
function truncate_utf8($string, $max_length, $wordsafe = FALSE, $add_ellipsis = FALSE, $min_wordsafe_length = 1) {
|
||||||
@@ -356,8 +361,7 @@ function truncate_utf8($string, $max_length, $wordsafe = FALSE, $add_ellipsis =
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encodes MIME/HTTP header values that contain non-ASCII, UTF-8 encoded
|
* Encodes MIME/HTTP header values that contain incorrectly encoded characters.
|
||||||
* characters.
|
|
||||||
*
|
*
|
||||||
* For example, mime_header_encode('tést.txt') returns "=?UTF-8?B?dMOpc3QudHh0?=".
|
* For example, mime_header_encode('tést.txt') returns "=?UTF-8?B?dMOpc3QudHh0?=".
|
||||||
*
|
*
|
||||||
@@ -369,6 +373,14 @@ function truncate_utf8($string, $max_length, $wordsafe = FALSE, $add_ellipsis =
|
|||||||
* each chunk starts and ends on a character boundary.
|
* each chunk starts and ends on a character boundary.
|
||||||
* - Using \n as the chunk separator may cause problems on some systems and may
|
* - Using \n as the chunk separator may cause problems on some systems and may
|
||||||
* have to be changed to \r\n or \r.
|
* have to be changed to \r\n or \r.
|
||||||
|
*
|
||||||
|
* @param $string
|
||||||
|
* The header to encode.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The mime-encoded header.
|
||||||
|
*
|
||||||
|
* @see mime_header_decode()
|
||||||
*/
|
*/
|
||||||
function mime_header_encode($string) {
|
function mime_header_encode($string) {
|
||||||
if (preg_match('/[^\x20-\x7E]/', $string)) {
|
if (preg_match('/[^\x20-\x7E]/', $string)) {
|
||||||
@@ -388,7 +400,15 @@ function mime_header_encode($string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Complement to mime_header_encode
|
* Decodes MIME/HTTP encoded header values.
|
||||||
|
*
|
||||||
|
* @param $header
|
||||||
|
* The header to decode.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The mime-decoded header.
|
||||||
|
*
|
||||||
|
* @see mime_header_encode()
|
||||||
*/
|
*/
|
||||||
function mime_header_decode($header) {
|
function mime_header_decode($header) {
|
||||||
// First step: encoded chunks followed by other encoded chunks (need to collapse whitespace)
|
// First step: encoded chunks followed by other encoded chunks (need to collapse whitespace)
|
||||||
@@ -398,7 +418,17 @@ function mime_header_decode($header) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to mime_header_decode
|
* Decodes encoded header data passed from mime_header_decode().
|
||||||
|
*
|
||||||
|
* Callback for preg_replace_callback() within mime_header_decode().
|
||||||
|
*
|
||||||
|
* @param $matches
|
||||||
|
* The array of matches from preg_replace_callback().
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The mime-decoded string.
|
||||||
|
*
|
||||||
|
* @see mime_header_decode()
|
||||||
*/
|
*/
|
||||||
function _mime_header_decode($matches) {
|
function _mime_header_decode($matches) {
|
||||||
// Regexp groups:
|
// Regexp groups:
|
||||||
@@ -415,9 +445,9 @@ function _mime_header_decode($matches) {
|
|||||||
/**
|
/**
|
||||||
* Decodes all HTML entities (including numerical ones) to regular UTF-8 bytes.
|
* Decodes all HTML entities (including numerical ones) to regular UTF-8 bytes.
|
||||||
*
|
*
|
||||||
* Double-escaped entities will only be decoded once ("&lt;" becomes "<",
|
* Double-escaped entities will only be decoded once ("&lt;" becomes "<"
|
||||||
* not "<"). Be careful when using this function, as decode_entities can revert
|
* , not "<"). Be careful when using this function, as decode_entities can
|
||||||
* previous sanitization efforts (<script> will become <script>).
|
* revert previous sanitization efforts (<script> will become <script>).
|
||||||
*
|
*
|
||||||
* @param $text
|
* @param $text
|
||||||
* The text to decode entities in.
|
* The text to decode entities in.
|
||||||
@@ -430,8 +460,15 @@ function decode_entities($text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count the amount of characters in a UTF-8 string. This is less than or
|
* Counts the number of characters in a UTF-8 string.
|
||||||
* equal to the byte count.
|
*
|
||||||
|
* This is less than or equal to the byte count.
|
||||||
|
*
|
||||||
|
* @param $text
|
||||||
|
* The string to run the operation on.
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
* The length of the string.
|
||||||
*
|
*
|
||||||
* @ingroup php_wrappers
|
* @ingroup php_wrappers
|
||||||
*/
|
*/
|
||||||
@@ -449,6 +486,12 @@ function drupal_strlen($text) {
|
|||||||
/**
|
/**
|
||||||
* Uppercase a UTF-8 string.
|
* Uppercase a UTF-8 string.
|
||||||
*
|
*
|
||||||
|
* @param $text
|
||||||
|
* The string to run the operation on.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The string in uppercase.
|
||||||
|
*
|
||||||
* @ingroup php_wrappers
|
* @ingroup php_wrappers
|
||||||
*/
|
*/
|
||||||
function drupal_strtoupper($text) {
|
function drupal_strtoupper($text) {
|
||||||
@@ -468,6 +511,12 @@ function drupal_strtoupper($text) {
|
|||||||
/**
|
/**
|
||||||
* Lowercase a UTF-8 string.
|
* Lowercase a UTF-8 string.
|
||||||
*
|
*
|
||||||
|
* @param $text
|
||||||
|
* The string to run the operation on.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The string in lowercase.
|
||||||
|
*
|
||||||
* @ingroup php_wrappers
|
* @ingroup php_wrappers
|
||||||
*/
|
*/
|
||||||
function drupal_strtolower($text) {
|
function drupal_strtolower($text) {
|
||||||
@@ -485,15 +534,28 @@ function drupal_strtolower($text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function for case conversion of Latin-1.
|
* Flips U+C0-U+DE to U+E0-U+FD and back.
|
||||||
* Used for flipping U+C0-U+DE to U+E0-U+FD and back.
|
*
|
||||||
|
* @param $matches
|
||||||
|
* An array of matches.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* The Latin-1 version of the array of matches.
|
||||||
|
*
|
||||||
|
* @see drupal_strtolower()
|
||||||
*/
|
*/
|
||||||
function _unicode_caseflip($matches) {
|
function _unicode_caseflip($matches) {
|
||||||
return $matches[0][0] . chr(ord($matches[0][1]) ^ 32);
|
return $matches[0][0] . chr(ord($matches[0][1]) ^ 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Capitalize the first letter of a UTF-8 string.
|
* Capitalizes the first letter of a UTF-8 string.
|
||||||
|
*
|
||||||
|
* @param $text
|
||||||
|
* The string to convert.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The string with the first letter as uppercase.
|
||||||
*
|
*
|
||||||
* @ingroup php_wrappers
|
* @ingroup php_wrappers
|
||||||
*/
|
*/
|
||||||
@@ -503,12 +565,21 @@ function drupal_ucfirst($text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cut off a piece of a string based on character indices and counts. Follows
|
* Cuts off a piece of a string based on character indices and counts.
|
||||||
* the same behavior as PHP's own substr() function.
|
|
||||||
*
|
*
|
||||||
* Note that for cutting off a string at a known character/substring
|
* Follows the same behavior as PHP's own substr() function. Note that for
|
||||||
* location, the usage of PHP's normal strpos/substr is safe and
|
* cutting off a string at a known character/substring location, the usage of
|
||||||
* much faster.
|
* PHP's normal strpos/substr is safe and much faster.
|
||||||
|
*
|
||||||
|
* @param $text
|
||||||
|
* The input string.
|
||||||
|
* @param $start
|
||||||
|
* The position at which to start reading.
|
||||||
|
* @param $length
|
||||||
|
* The number of characters to read.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The shortened string.
|
||||||
*
|
*
|
||||||
* @ingroup php_wrappers
|
* @ingroup php_wrappers
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ function update_fix_compatibility() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to test compatibility of a module or theme.
|
* Tests the compatibility of a module or theme.
|
||||||
*/
|
*/
|
||||||
function update_check_incompatibility($name, $type = 'module') {
|
function update_check_incompatibility($name, $type = 'module') {
|
||||||
static $themes, $modules;
|
static $themes, $modules;
|
||||||
@@ -908,7 +908,7 @@ function update_get_d6_session_name() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform one update and store the results for display on finished page.
|
* Performs one update and stores the results for display on the results page.
|
||||||
*
|
*
|
||||||
* If an update function completes successfully, it should return a message
|
* If an update function completes successfully, it should return a message
|
||||||
* as a string indicating success, for example:
|
* as a string indicating success, for example:
|
||||||
@@ -1008,7 +1008,7 @@ function update_do_one($module, $number, $dependency_map, &$context) {
|
|||||||
class DrupalUpdateException extends Exception { }
|
class DrupalUpdateException extends Exception { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the database update batch process.
|
* Starts the database update batch process.
|
||||||
*
|
*
|
||||||
* @param $start
|
* @param $start
|
||||||
* An array whose keys contain the names of modules to be updated during the
|
* An array whose keys contain the names of modules to be updated during the
|
||||||
@@ -1078,7 +1078,7 @@ function update_batch($start, $redirect = NULL, $url = NULL, $batch = array(), $
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finish the update process and store results for eventual display.
|
* Finishes the update process and stores the results for eventual display.
|
||||||
*
|
*
|
||||||
* After the updates run, all caches are flushed. The update results are
|
* After the updates run, all caches are flushed. The update results are
|
||||||
* stored into the session (for example, to be displayed on the update results
|
* stored into the session (for example, to be displayed on the update results
|
||||||
@@ -1115,7 +1115,7 @@ function update_finished($success, $results, $operations) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a list of all the pending database updates.
|
* Returns a list of all the pending database updates.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* An associative array keyed by module name which contains all information
|
* An associative array keyed by module name which contains all information
|
||||||
@@ -1409,7 +1409,7 @@ function update_already_performed($module, $number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke hook_update_dependencies() in all installed modules.
|
* Invokes hook_update_dependencies() in all installed modules.
|
||||||
*
|
*
|
||||||
* This function is similar to module_invoke_all(), with the main difference
|
* This function is similar to module_invoke_all(), with the main difference
|
||||||
* that it does not require that a module be enabled to invoke its hook, only
|
* that it does not require that a module be enabled to invoke its hook, only
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* The variable to export.
|
* The variable to export.
|
||||||
* @param $prefix
|
* @param $prefix
|
||||||
* A prefix that will be added at the beginning of every lines of the output.
|
* A prefix that will be added at the beginning of every lines of the output.
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
* The variable exported in a way compatible to Drupal's coding standards.
|
* The variable exported in a way compatible to Drupal's coding standards.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* Initiates a browser-based installation of Drupal.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Root directory of Drupal installation.
|
|
||||||
*/
|
|
||||||
define('DRUPAL_ROOT', getcwd());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Global flag to indicate that site is in installation mode.
|
|
||||||
*/
|
|
||||||
define('MAINTENANCE_MODE', 'install');
|
|
||||||
|
|
||||||
// Exit early if running an incompatible PHP version to avoid fatal errors.
|
|
||||||
if (version_compare(PHP_VERSION, '5.2.4') < 0) {
|
|
||||||
print 'Your PHP installation is too old. Drupal requires at least PHP 5.2.4. See the <a href="http://drupal.org/requirements">system requirements</a> page for more information.';
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the installer.
|
|
||||||
require_once DRUPAL_ROOT . '/includes/install.core.inc';
|
|
||||||
install_drupal();
|
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->
|
||||||
|
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en" dir="ltr" > <![endif]-->
|
||||||
|
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en" dir="ltr" > <![endif]-->
|
||||||
|
<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en" dir="ltr" > <![endif]-->
|
||||||
|
<!-- Consider adding an manifest.appcache: h5bp.com/d/Offline -->
|
||||||
|
<!--[if gt IE 8]><!-->
|
||||||
|
<html class="js no-flexbox canvas canvastext webgl no-touch geolocation postmessage no-websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients no-cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths" dir="ltr" lang="en"><!--<![endif]-->
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
|
||||||
|
Remove this if you use the .htaccess -->
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
|
|
||||||
|
<link type="image/png" rel="shortcut icon" href="http://www.materio.com/sites/all/themes/gui/materiobasetheme/materio-icon-O.png">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<link rel="alternate" type="application/rss+xml" title="Materio's news" href="http://www.materio.com/en/rss/feed">
|
||||||
|
|
||||||
|
<title>Site under maintenance | materiO’</title>
|
||||||
|
<style type="text/css" media="all">
|
||||||
|
@import url("http://www.materio.com/modules/system/system.base.css?mu8p7n");
|
||||||
|
@import url("http://www.materio.com/modules/system/system.menus.css?mu8p7n");
|
||||||
|
@import url("http://www.materio.com/modules/system/system.theme.css?mu8p7n");
|
||||||
|
</style>
|
||||||
|
<style type="text/css" media="all">
|
||||||
|
@import url("http://www.materio.com/sites/all/modules/contrib/mail/simplenews/simplenews.css?mu8p7n");
|
||||||
|
@import url("http://www.materio.com/modules/field/theme/field.css?mu8p7n");
|
||||||
|
@import url("http://www.materio.com/modules/node/node.css?mu8p7n");
|
||||||
|
</style>
|
||||||
|
<style type="text/css" media="all">
|
||||||
|
@import url("http://www.materio.com/sites/all/modules/contrib/theming/extlink/extlink.css?mu8p7n");
|
||||||
|
</style>
|
||||||
|
<style type="text/css" media="all">
|
||||||
|
@import url("http://www.materio.com/sites/all/themes/gui/materiobasetheme/css/normalize.css?mu8p7n");
|
||||||
|
@import url("http://www.materio.com/sites/all/themes/gui/materiobasetheme/fonts/ubuntu/ubuntu.css?mu8p7n");
|
||||||
|
@import url("http://www.materio.com/sites/all/themes/gui/materiobasetheme/css/styles.css?mu8p7n");
|
||||||
|
@import url("http://www.materio.com/sites/all/themes/gui/materiobasetheme/css/nonsemantic.css?mu8p7n");
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- All JavaScript at the bottom, except for Modernizr / Respond.
|
||||||
|
|
||||||
|
|
||||||
|
<!--[if lt IE 9]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="maintenance-page in-maintenance no-sidebars">
|
||||||
|
<div id="root">
|
||||||
|
|
||||||
|
<div id="container">
|
||||||
|
|
||||||
|
<header id="header">
|
||||||
|
<h1 class="site-name">materiO’</h1>
|
||||||
|
<h2 class="site-slogan">l'inspiration par la matière </h2>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div id="main">
|
||||||
|
|
||||||
|
<section id="center">
|
||||||
|
|
||||||
|
<section id="content">
|
||||||
|
<div class="inner-content">
|
||||||
|
<h3 class="page-title">Site under maintenance</h3> <p>materiO' is currently working hard to make a better service for you !<br>We should be back shortly.<br>Thank you for your patience.</p>
|
||||||
|
<img src="index_files/maintenance.jpg">
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</section> <!-- /center -->
|
||||||
|
|
||||||
|
</div><!-- /main -->
|
||||||
|
|
||||||
|
<div id="footer"></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- /container -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- /root -->
|
||||||
|
|
||||||
|
|
||||||
|
<div style="display: none;" id="cboxOverlay"></div><div style="display: none;" tabindex="-1" role="dialog" class="" id="colorbox"><div id="cboxWrapper"><div><div style="float: left;" id="cboxTopLeft"></div><div style="float: left;" id="cboxTopCenter"></div><div style="float: left;" id="cboxTopRight"></div></div><div style="clear: left;"><div style="float: left;" id="cboxMiddleLeft"></div><div style="float: left;" id="cboxContent"><div style="float: left;" id="cboxTitle"></div><div style="float: left;" id="cboxCurrent"></div><button id="cboxPrevious" type="button"></button><button id="cboxNext" type="button"></button><button id="cboxSlideshow"></button><div style="float: left;" id="cboxLoadingOverlay"></div><div style="float: left;" id="cboxLoadingGraphic"></div><button id="cboxClose" type="button"></button></div><div style="float: left;" id="cboxMiddleRight"></div></div><div style="clear: left;"><div style="float: left;" id="cboxBottomLeft"></div><div style="float: left;" id="cboxBottomCenter"></div><div style="float: left;" id="cboxBottomRight"></div></div></div><div style="position: absolute; width: 9999px; visibility: hidden; display: none;"></div></div></body></html>
|
||||||
|
After Width: | Height: | Size: 16 KiB |
@@ -396,7 +396,7 @@ Drupal.ajax.prototype.success = function (response, status) {
|
|||||||
Drupal.freezeHeight();
|
Drupal.freezeHeight();
|
||||||
|
|
||||||
for (var i in response) {
|
for (var i in response) {
|
||||||
if (response[i]['command'] && this.commands[response[i]['command']]) {
|
if (response.hasOwnProperty(i) && response[i]['command'] && this.commands[response[i]['command']]) {
|
||||||
this.commands[response[i]['command']](this, response[i], status);
|
this.commands[response[i]['command']](this, response[i], status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -616,6 +616,13 @@ Drupal.ajax.prototype.commands = {
|
|||||||
.removeClass('odd even')
|
.removeClass('odd even')
|
||||||
.filter(':even').addClass('odd').end()
|
.filter(':even').addClass('odd').end()
|
||||||
.filter(':odd').addClass('even');
|
.filter(':odd').addClass('even');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Command to update a form's build ID.
|
||||||
|
*/
|
||||||
|
updateBuildId: function(ajax, response, status) {
|
||||||
|
$('input[name="form_build_id"][value="' + response['old'] + '"]').val(response['new']);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 118 B |
|
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 118 B |
@@ -114,6 +114,7 @@ Drupal.jsAC.prototype.onkeyup = function (input, e) {
|
|||||||
*/
|
*/
|
||||||
Drupal.jsAC.prototype.select = function (node) {
|
Drupal.jsAC.prototype.select = function (node) {
|
||||||
this.input.value = $(node).data('autocompleteValue');
|
this.input.value = $(node).data('autocompleteValue');
|
||||||
|
$(this.input).trigger('autocompleteSelect', [node]);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -167,7 +168,7 @@ Drupal.jsAC.prototype.unhighlight = function (node) {
|
|||||||
Drupal.jsAC.prototype.hidePopup = function (keycode) {
|
Drupal.jsAC.prototype.hidePopup = function (keycode) {
|
||||||
// Select item if the right key or mousebutton was pressed.
|
// Select item if the right key or mousebutton was pressed.
|
||||||
if (this.selected && ((keycode && keycode != 46 && keycode != 8 && keycode != 27) || !keycode)) {
|
if (this.selected && ((keycode && keycode != 46 && keycode != 8 && keycode != 27) || !keycode)) {
|
||||||
this.input.value = $(this.selected).data('autocompleteValue');
|
this.select(this.selected);
|
||||||
}
|
}
|
||||||
// Hide popup.
|
// Hide popup.
|
||||||
var popup = this.popup;
|
var popup = this.popup;
|
||||||
@@ -220,7 +221,7 @@ Drupal.jsAC.prototype.found = function (matches) {
|
|||||||
for (key in matches) {
|
for (key in matches) {
|
||||||
$('<li></li>')
|
$('<li></li>')
|
||||||
.html($('<div></div>').html(matches[key]))
|
.html($('<div></div>').html(matches[key]))
|
||||||
.mousedown(function () { ac.select(this); })
|
.mousedown(function () { ac.hidePopup(this); })
|
||||||
.mouseover(function () { ac.highlight(this); })
|
.mouseover(function () { ac.highlight(this); })
|
||||||
.mouseout(function () { ac.unhighlight(this); })
|
.mouseout(function () { ac.unhighlight(this); })
|
||||||
.data('autocompleteValue', key)
|
.data('autocompleteValue', key)
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 248 B After Width: | Height: | Size: 248 B |
|
Before Width: | Height: | Size: 268 B After Width: | Height: | Size: 268 B |