Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
@@ -116,6 +116,24 @@ DirectoryIndex index.php index.html index.htm
|
||||
RewriteCond %{REQUEST_URI} !=/favicon.ico
|
||||
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.
|
||||
# Requires both mod_rewrite and mod_headers to be enabled.
|
||||
<IfModule mod_headers.c>
|
||||
|
||||
@@ -1,4 +1,168 @@
|
||||
|
||||
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
|
||||
@@ -53,7 +217,7 @@ Drupal 7.22, 2013-04-03
|
||||
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).
|
||||
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
|
||||
|
||||
@@ -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
|
||||
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.
|
||||
|
||||
More about installation profiles and distributions:
|
||||
* Read about the difference between installation profiles and distributions:
|
||||
http://drupal.org/node/1089736
|
||||
* Download contributed installation profiles and distributions:
|
||||
http://drupal.org/project/distributions
|
||||
* Develop your own installation profile or distribution:
|
||||
http://drupal.org/developing/distributions
|
||||
* Read about the difference between installation profiles and distributions:
|
||||
http://drupal.org/node/1089736
|
||||
* Download contributed installation profiles and distributions:
|
||||
http://drupal.org/project/distributions
|
||||
* Develop your own installation profile or distribution:
|
||||
http://drupal.org/developing/distributions
|
||||
|
||||
APPEARANCE
|
||||
----------
|
||||
|
||||
@@ -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 |
@@ -308,10 +308,11 @@ function ajax_render($commands = array()) {
|
||||
* pulls the form info from $_POST.
|
||||
*
|
||||
* @return
|
||||
* An array containing the $form and $form_state. Use the list() function
|
||||
* to break these apart:
|
||||
* An array containing the $form, $form_state, $form_id, $form_build_id and an
|
||||
* initial list of Ajax $commands. Use the list() function to break these
|
||||
* apart:
|
||||
* @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
|
||||
*/
|
||||
function ajax_get_form() {
|
||||
@@ -331,6 +332,17 @@ function ajax_get_form() {
|
||||
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.
|
||||
$form_state['no_redirect'] = TRUE;
|
||||
|
||||
@@ -345,7 +357,7 @@ function ajax_get_form() {
|
||||
$form_state['input'] = $_POST;
|
||||
$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()
|
||||
*/
|
||||
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);
|
||||
|
||||
// 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'];
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1210,3 +1234,26 @@ function ajax_command_restripe($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.
|
||||
*/
|
||||
define('VERSION', '7.22');
|
||||
define('VERSION', '7.28');
|
||||
|
||||
/**
|
||||
* Core API compatibility.
|
||||
@@ -218,12 +218,16 @@ define('LANGUAGE_RTL', 1);
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
@@ -240,7 +244,7 @@ define('REGISTRY_WRITE_LOOKUP_CACHE', 2);
|
||||
/**
|
||||
* 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]*');
|
||||
|
||||
@@ -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
|
||||
* 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·
|
||||
* http://php.net/manual/en/arrayaccess.offsetget.php on
|
||||
* http://php.net/manual/arrayaccess.offsetget.php on
|
||||
* ArrayAccess::offsetGet().
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @param $offset
|
||||
* The array offset that was request.
|
||||
* The array offset that was requested.
|
||||
* @param $persist
|
||||
* Optional boolean to specify whether the offset should be persisted or
|
||||
* 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) {
|
||||
$this->keysToPersist[$offset] = $persist;
|
||||
@@ -679,7 +683,8 @@ function drupal_environment_initialize() {
|
||||
ini_set('session.use_only_cookies', '1');
|
||||
ini_set('session.use_trans_sid', '0');
|
||||
// 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.
|
||||
ini_set('session.cookie_httponly', '1');
|
||||
|
||||
@@ -791,7 +796,7 @@ function drupal_settings_initialize() {
|
||||
*
|
||||
* 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
|
||||
* 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:
|
||||
*
|
||||
* modules/foo/foo.module
|
||||
@@ -802,7 +807,7 @@ function drupal_settings_initialize() {
|
||||
* the above, depending on where the module is located.
|
||||
*
|
||||
* @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
|
||||
* The name of the item for which the filename is requested.
|
||||
* @param $filename
|
||||
@@ -1274,7 +1279,7 @@ function drupal_page_header() {
|
||||
*/
|
||||
function drupal_serve_page_from_cache(stdClass $cache) {
|
||||
// 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;
|
||||
|
||||
// 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
|
||||
* break up strings for translation.
|
||||
*
|
||||
* @section sec_translating_vars Translating Variables
|
||||
* You should never use t() to translate variables, such as calling
|
||||
* @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
|
||||
@@ -1424,6 +1430,7 @@ function drupal_unpack($obj, $field = 'data') {
|
||||
* 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
|
||||
* available to code that needs localization. See st() and get_t() for
|
||||
* alternatives.
|
||||
@@ -1926,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).
|
||||
*
|
||||
@@ -1939,38 +1973,34 @@ function drupal_block_denied($ip) {
|
||||
*/
|
||||
function drupal_random_bytes($count) {
|
||||
// $random_state does not use drupal_static as it stores random bytes.
|
||||
static $random_state, $bytes, $php_compatible;
|
||||
// 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.
|
||||
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 = '';
|
||||
}
|
||||
if (strlen($bytes) < $count) {
|
||||
static $random_state, $bytes, $has_openssl;
|
||||
|
||||
$missing_bytes = $count - strlen($bytes);
|
||||
|
||||
if ($missing_bytes > 0) {
|
||||
// PHP versions prior 5.3.4 experienced openssl_random_pseudo_bytes()
|
||||
// locking on Windows and rendered it unusable.
|
||||
if (!isset($php_compatible)) {
|
||||
$php_compatible = version_compare(PHP_VERSION, '5.3.4', '>=');
|
||||
if (!isset($has_openssl)) {
|
||||
$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.
|
||||
if ($fh = @fopen('/dev/urandom', 'rb')) {
|
||||
|
||||
// openssl_random_pseudo_bytes() will find entropy in a system-dependent
|
||||
// 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
|
||||
// at least 4096 bytes. Thus, it costs nothing extra to read and store
|
||||
// that much so as to speed any additional invocations.
|
||||
$bytes .= fread($fh, max(4096, $count));
|
||||
$bytes .= fread($fh, max(4096, $missing_bytes));
|
||||
fclose($fh);
|
||||
}
|
||||
// openssl_random_pseudo_bytes() will find entropy in a system-dependent
|
||||
// way.
|
||||
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
|
||||
|
||||
// If we couldn't get enough entropy, this simple hash-based PRNG will
|
||||
// generate a good set of pseudo-random bytes on any system.
|
||||
// Note that it may be important that our $random_state is passed
|
||||
// through hash() prior to being rolled into $output, that the two hash()
|
||||
@@ -1978,9 +2008,23 @@ function drupal_random_bytes($count) {
|
||||
// the microtime() - is prepended rather than appended. This is to avoid
|
||||
// directly leaking $random_state via the $output stream, which could
|
||||
// allow for trivial prediction of further "random" numbers.
|
||||
while (strlen($bytes) < $count) {
|
||||
$random_state = hash('sha256', microtime() . mt_rand() . $random_state);
|
||||
$bytes .= hash('sha256', mt_rand() . $random_state, TRUE);
|
||||
if (strlen($bytes) < $count) {
|
||||
// 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.
|
||||
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);
|
||||
@@ -1991,17 +2035,21 @@ function drupal_random_bytes($count) {
|
||||
/**
|
||||
* Calculates a base-64 encoded, URL-safe sha-256 hmac.
|
||||
*
|
||||
* @param $data
|
||||
* @param string $data
|
||||
* String to be validated with the hmac.
|
||||
* @param $key
|
||||
* @param string $key
|
||||
* A secret string key.
|
||||
*
|
||||
* @return
|
||||
* @return string
|
||||
* A base-64 encoded sha-256 hmac, with + replaced with -, / with _ and
|
||||
* any = padding characters removed.
|
||||
*/
|
||||
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.
|
||||
return strtr($hmac, array('+' => '-', '/' => '_', '=' => ''));
|
||||
}
|
||||
@@ -2102,7 +2150,7 @@ function drupal_array_merge_deep_array($arrays) {
|
||||
* @return Object - the user object.
|
||||
*/
|
||||
function drupal_anonymous_user() {
|
||||
$user = new stdClass();
|
||||
$user = variable_get('drupal_anonymous_user_object', new stdClass);
|
||||
$user->uid = 0;
|
||||
$user->hostname = ip_address();
|
||||
$user->roles = array();
|
||||
@@ -2232,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.
|
||||
*
|
||||
@@ -2452,7 +2513,6 @@ function drupal_get_bootstrap_phase() {
|
||||
* HMAC and timestamp.
|
||||
*/
|
||||
function drupal_valid_test_ua() {
|
||||
global $drupal_hash_salt;
|
||||
// No reason to reset this.
|
||||
static $test_prefix;
|
||||
|
||||
@@ -2466,7 +2526,7 @@ function drupal_valid_test_ua() {
|
||||
// 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 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;
|
||||
// Since we are making a local request a 5 second time window is allowed,
|
||||
// and the HMAC must match.
|
||||
@@ -2484,14 +2544,13 @@ function drupal_valid_test_ua() {
|
||||
* Generates a user agent string with a HMAC and timestamp for simpletest.
|
||||
*/
|
||||
function drupal_generate_test_ua($prefix) {
|
||||
global $drupal_hash_salt;
|
||||
static $key;
|
||||
|
||||
if (!isset($key)) {
|
||||
// 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 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.
|
||||
$salt = uniqid('', TRUE);
|
||||
@@ -3236,8 +3295,8 @@ function registry_update() {
|
||||
* 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 assigned to references.
|
||||
* - http://php.net/manual/en/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.static
|
||||
* - http://php.net/manual/language.variables.scope.php#language.variables.scope.references
|
||||
* The example below shows the syntax needed to work around both limitations.
|
||||
* For benchmarks and more information, see http://drupal.org/node/619666.
|
||||
*
|
||||
@@ -3397,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)));
|
||||
}
|
||||
|
||||
@@ -137,18 +137,20 @@ function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) {
|
||||
/**
|
||||
* Expires data from the cache.
|
||||
*
|
||||
* If called without arguments, expirable entries will be cleared from the
|
||||
* cache_page and cache_block bins.
|
||||
* If called with the arguments $cid and $bin set to NULL or omitted, then
|
||||
* expirable entries will be cleared from the cache_page and cache_block bins,
|
||||
* and the $wildcard argument is ignored.
|
||||
*
|
||||
* @param $cid
|
||||
* If set, the cache ID to delete. Otherwise, all cache entries that can
|
||||
* expire are deleted.
|
||||
* If set, the cache ID or an array of cache IDs. Otherwise, all cache entries
|
||||
* that can expire are deleted. The $wildcard argument will be ignored if set
|
||||
* to NULL.
|
||||
* @param $bin
|
||||
* If set, the cache bin to delete from. Mandatory argument if $cid is set.
|
||||
* @param $wildcard
|
||||
* If TRUE, cache IDs starting with $cid are deleted in addition to the
|
||||
* exact cache ID specified by $cid. If $wildcard is TRUE and $cid is '*',
|
||||
* the entire cache bin is emptied.
|
||||
* If TRUE, the $cid argument must contain a string value and cache IDs
|
||||
* starting with $cid are deleted in addition to the exact cache ID specified
|
||||
* by $cid. If $wildcard is TRUE and $cid is '*', the entire cache is emptied.
|
||||
*/
|
||||
function cache_clear_all($cid = NULL, $bin = NULL, $wildcard = FALSE) {
|
||||
if (!isset($cid) && !isset($bin)) {
|
||||
@@ -217,13 +219,6 @@ function cache_is_empty($bin) {
|
||||
* @see DrupalDatabaseCache
|
||||
*/
|
||||
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.
|
||||
@@ -280,12 +275,14 @@ interface DrupalCacheInterface {
|
||||
* cache_page and cache_block bins.
|
||||
*
|
||||
* @param $cid
|
||||
* If set, the cache ID to delete. Otherwise, all cache entries that can
|
||||
* expire are deleted.
|
||||
* If set, the cache ID or an array of cache IDs. Otherwise, all cache
|
||||
* entries that can expire are deleted. The $wildcard argument will be
|
||||
* ignored if set to NULL.
|
||||
* @param $wildcard
|
||||
* If set to TRUE, the $cid is treated as a substring
|
||||
* to match rather than a complete ID. The match is a right hand
|
||||
* match. If '*' is given as $cid, the bin $bin will be emptied.
|
||||
* If TRUE, the $cid argument must contain a string value and cache IDs
|
||||
* starting with $cid are deleted in addition to the exact cache ID
|
||||
* specified by $cid. If $wildcard is TRUE and $cid is '*', the entire
|
||||
* cache is emptied.
|
||||
*/
|
||||
function clear($cid = NULL, $wildcard = FALSE);
|
||||
|
||||
@@ -311,7 +308,10 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
|
||||
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) {
|
||||
$this->bin = $bin;
|
||||
@@ -505,7 +505,16 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
|
||||
else {
|
||||
if ($wildcard) {
|
||||
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 {
|
||||
db_delete($this->bin)
|
||||
@@ -542,4 +551,25 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
|
||||
->fetchField();
|
||||
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']));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -458,7 +458,7 @@ function drupal_get_query_array($query) {
|
||||
$result = array();
|
||||
if (!empty($query)) {
|
||||
foreach (explode('&', $query) as $param) {
|
||||
$param = explode('=', $param);
|
||||
$param = explode('=', $param, 2);
|
||||
$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
|
||||
* URL is formatted correctly.
|
||||
@@ -929,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 (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
|
||||
@@ -1134,7 +1134,7 @@ function _fix_gpc_magic(&$item) {
|
||||
* @param $key
|
||||
* 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) {
|
||||
if ($key != 'tmp_name') {
|
||||
@@ -1426,7 +1426,6 @@ function filter_xss_admin($string) {
|
||||
* valid UTF-8.
|
||||
*
|
||||
* @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')) {
|
||||
// Only operate on valid UTF-8 strings. This is necessary to prevent cross
|
||||
@@ -1950,7 +1949,7 @@ function format_interval($interval, $granularity = 2, $langcode = NULL) {
|
||||
* get interpreted as date format characters.
|
||||
* @param $timezone
|
||||
* (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.
|
||||
* @param $langcode
|
||||
* (optional) Language code to translate to. Defaults to the language used to
|
||||
@@ -2086,6 +2085,9 @@ function _format_date_callback(array $matches = NULL, $new_langcode = NULL) {
|
||||
/**
|
||||
* 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
|
||||
* else, the site-defined value for the 'anonymous' variable. However, a module
|
||||
* may override this by implementing hook_username_alter(&$name, $account).
|
||||
@@ -3670,17 +3672,23 @@ function drupal_load_stylesheet($file, $optimize = NULL, $reset_basepath = TRUE)
|
||||
if ($basepath && !file_uri_scheme($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);
|
||||
|
||||
// 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,
|
||||
// but are merely there to disable certain module CSS files.
|
||||
$content = '';
|
||||
if ($contents = @file_get_contents($file)) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3697,7 +3705,7 @@ function drupal_load_stylesheet($file, $optimize = NULL, $reset_basepath = TRUE)
|
||||
*/
|
||||
function drupal_load_stylesheet_content($contents, $optimize = FALSE) {
|
||||
// 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) {
|
||||
// Perform some safe CSS optimizations.
|
||||
@@ -3716,7 +3724,7 @@ function drupal_load_stylesheet_content($contents, $optimize = FALSE) {
|
||||
// Remove certain whitespace.
|
||||
// There are different conditions for removing leading and trailing
|
||||
// whitespace.
|
||||
// @see http://php.net/manual/en/regexp.reference.subpatterns.php
|
||||
// @see http://php.net/manual/regexp.reference.subpatterns.php
|
||||
$contents = preg_replace('<
|
||||
# Strip leading and trailing whitespace.
|
||||
\s*([@{};,])\s*
|
||||
@@ -3830,7 +3838,14 @@ function drupal_clean_css_identifier($identifier, $filter = array(' ' => '-', '_
|
||||
* The cleaned class name.
|
||||
*/
|
||||
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];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3885,14 +3900,14 @@ function drupal_html_id($id) {
|
||||
// requested id. $_POST['ajax_html_ids'] contains the ids as they were
|
||||
// returned by this function, potentially with the appended counter, so
|
||||
// we parse that to reconstruct the $seen_ids array.
|
||||
if (is_array($_POST['ajax_html_ids'])) {
|
||||
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 instead
|
||||
// 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']);
|
||||
// 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
|
||||
@@ -4094,7 +4109,7 @@ function drupal_region_class($region) {
|
||||
* 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
|
||||
* 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.
|
||||
* - 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
|
||||
@@ -5031,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.
|
||||
*
|
||||
@@ -5052,7 +5054,7 @@ function drupal_get_hash_salt() {
|
||||
*/
|
||||
function drupal_get_private_key() {
|
||||
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);
|
||||
}
|
||||
return $key;
|
||||
@@ -5064,10 +5066,17 @@ function drupal_get_private_key() {
|
||||
* @param $value
|
||||
* 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 global $drupal_hash_salt variable from settings.php, and the
|
||||
* 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 = '') {
|
||||
return drupal_hmac_base64($value, session_id() . drupal_get_private_key() . drupal_get_hash_salt());
|
||||
@@ -5089,7 +5098,7 @@ function drupal_get_token($value = '') {
|
||||
*/
|
||||
function drupal_valid_token($token, $value = '', $skip_anonymous = FALSE) {
|
||||
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() {
|
||||
@@ -5122,6 +5131,10 @@ function _drupal_bootstrap_full() {
|
||||
module_load_all();
|
||||
// Make sure all stream wrappers are registered.
|
||||
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'];
|
||||
if (!empty($test_info['in_child_site'])) {
|
||||
@@ -5159,7 +5172,7 @@ function _drupal_bootstrap_full() {
|
||||
* client without gzip support.
|
||||
*
|
||||
* 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()
|
||||
*/
|
||||
@@ -5167,6 +5180,10 @@ function drupal_page_set_cache() {
|
||||
global $base_root;
|
||||
|
||||
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(
|
||||
'cid' => $base_root . request_uri(),
|
||||
'data' => array(
|
||||
@@ -5174,6 +5191,9 @@ function drupal_page_set_cache() {
|
||||
'body' => ob_get_clean(),
|
||||
'title' => drupal_get_title(),
|
||||
'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,
|
||||
'created' => REQUEST_TIME,
|
||||
@@ -5191,7 +5211,7 @@ function drupal_page_set_cache() {
|
||||
}
|
||||
|
||||
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_set($cache->cid, $cache->data, 'cache_page', $cache->expire);
|
||||
@@ -5266,12 +5286,23 @@ function drupal_cron_run() {
|
||||
}
|
||||
|
||||
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'];
|
||||
$end = time() + (isset($info['time']) ? $info['time'] : 15);
|
||||
$queue = DrupalQueue::get($queue_name);
|
||||
while (time() < $end && ($item = $queue->claimItem())) {
|
||||
$function($item->data);
|
||||
$queue->deleteItem($item);
|
||||
try {
|
||||
$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.
|
||||
@@ -5803,23 +5834,23 @@ function drupal_render_page($page) {
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* @return
|
||||
* @return string
|
||||
* The rendered HTML.
|
||||
*/
|
||||
function drupal_render(&$elements) {
|
||||
// Early-return nothing if user does not have access.
|
||||
if (empty($elements) || (isset($elements['#access']) && !$elements['#access'])) {
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
|
||||
// Do not print elements twice.
|
||||
if (!empty($elements['#printed'])) {
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
|
||||
// Try to fetch the element's markup from cache and return.
|
||||
@@ -5855,7 +5886,7 @@ function drupal_render(&$elements) {
|
||||
|
||||
// Allow #pre_render to abort rendering.
|
||||
if (!empty($elements['#printed'])) {
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
|
||||
// Get the children of the element, sorted by weight.
|
||||
@@ -5926,14 +5957,16 @@ function drupal_render(&$elements) {
|
||||
/**
|
||||
* Renders children of an element and concatenates them.
|
||||
*
|
||||
* This renders all children of an element using drupal_render() and then
|
||||
* joins them together into a single string.
|
||||
*
|
||||
* @param $element
|
||||
* @param array $element
|
||||
* The structured array whose children shall be rendered.
|
||||
* @param $children_keys
|
||||
* If the keys of the element's children are already known, they can be passed
|
||||
* in to save another run of element_children().
|
||||
* @param array $children_keys
|
||||
* (optional) If the keys of the element's children are already known, they
|
||||
* 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) {
|
||||
if ($children_keys === NULL) {
|
||||
@@ -6477,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.
|
||||
*
|
||||
@@ -7769,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) {
|
||||
$controllers = &drupal_static(__FUNCTION__, array());
|
||||
|
||||
@@ -28,18 +28,21 @@
|
||||
* 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
|
||||
* Extender for queries that return results that need to be presented on
|
||||
* multiple pages, and the Tablesort Extender for generating appropriate queries
|
||||
* for sortable tables.
|
||||
* multiple pages (see https://drupal.org/node/508796), and the TableSort
|
||||
* 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
|
||||
* authored by a given user. Instead of directly issuing the SQL query
|
||||
* @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
|
||||
* one would instead call the Drupal functions:
|
||||
* @code
|
||||
* $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) {
|
||||
* // Perform operations on $record->title, etc. here.
|
||||
* }
|
||||
@@ -179,7 +182,7 @@
|
||||
* concrete implementation of it to support special handling required by that
|
||||
* database.
|
||||
*
|
||||
* @see http://php.net/manual/en/book.pdo.php
|
||||
* @see http://php.net/manual/book.pdo.php
|
||||
*/
|
||||
abstract class DatabaseConnection extends PDO {
|
||||
|
||||
@@ -1986,7 +1989,7 @@ interface DatabaseStatementInterface extends Traversable {
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param $mode
|
||||
@@ -2005,7 +2008,7 @@ interface DatabaseStatementInterface extends Traversable {
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param $mode
|
||||
@@ -2380,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.
|
||||
*
|
||||
* @param $query
|
||||
* The prepared statement query to run. Although it will accept both named and
|
||||
* unnamed placeholders, named placeholders are strongly preferred as they are
|
||||
* more self-documenting.
|
||||
* The prepared SELECT statement query to run. Although it will accept both
|
||||
* named and unnamed placeholders, named placeholders are strongly preferred
|
||||
* as they are more self-documenting.
|
||||
* @param $args
|
||||
* 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
|
||||
|
||||
@@ -90,7 +90,7 @@ class DatabaseConnection_mysql extends DatabaseConnection {
|
||||
|
||||
public function queryTemporary($query, array $args = array(), array $options = array()) {
|
||||
$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;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,8 @@ class InsertQuery_mysql extends InsertQuery {
|
||||
// If we're selecting from a SelectQuery, finish building the query and
|
||||
// pass it back, as any remaining options are irrelevant.
|
||||
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 ';
|
||||
@@ -86,21 +87,7 @@ class InsertQuery_mysql extends InsertQuery {
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
class TruncateQuery_mysql extends TruncateQuery { }
|
||||
|
||||
/**
|
||||
* @} End of "addtogroup database".
|
||||
|
||||
@@ -146,7 +146,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
|
||||
|
||||
public function queryTemporary($query, array $args = array(), array $options = array()) {
|
||||
$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;
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +112,8 @@ class InsertQuery_pgsql extends InsertQuery {
|
||||
// If we're selecting from a SelectQuery, finish building the query and
|
||||
// pass it back, as any remaining options are irrelevant.
|
||||
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 ';
|
||||
|
||||
@@ -83,7 +83,7 @@ interface QueryConditionInterface {
|
||||
|
||||
/**
|
||||
* Sets a condition that the specified subquery returns values.
|
||||
*
|
||||
*
|
||||
* @param SelectQueryInterface $select
|
||||
* The subquery that must contain results.
|
||||
*
|
||||
@@ -91,10 +91,10 @@ interface QueryConditionInterface {
|
||||
* The called object.
|
||||
*/
|
||||
public function exists(SelectQueryInterface $select);
|
||||
|
||||
|
||||
/**
|
||||
* Sets a condition that the specified subquery returns no values.
|
||||
*
|
||||
*
|
||||
* @param SelectQueryInterface $select
|
||||
* The subquery that must not contain results.
|
||||
*
|
||||
@@ -102,7 +102,7 @@ interface QueryConditionInterface {
|
||||
* The called object.
|
||||
*/
|
||||
public function notExists(SelectQueryInterface $select);
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $connectionTarget;
|
||||
|
||||
/**
|
||||
* The key of the connection object.
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $connectionKey;
|
||||
@@ -710,10 +710,11 @@ class InsertQuery extends Query {
|
||||
// first call to fields() does have an effect.
|
||||
$this->fields(array_merge(array_keys($this->fromQuery->getFields()), array_keys($this->fromQuery->getExpressions())));
|
||||
}
|
||||
|
||||
// Don't execute query without fields.
|
||||
if (count($this->insertFields) + count($this->defaultFields) == 0) {
|
||||
throw new NoFieldsException('There are no fields available to insert with.');
|
||||
else {
|
||||
// Don't execute query without fields.
|
||||
if (count($this->insertFields) + count($this->defaultFields) == 0) {
|
||||
throw new NoFieldsException('There are no fields available to insert with.');
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements QueryConditionInterface::conditions().
|
||||
*/
|
||||
@@ -942,7 +943,17 @@ class TruncateQuery extends Query {
|
||||
// Create a sanitized comment string to prepend to the query.
|
||||
$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);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements QueryConditionInterface::conditions().
|
||||
*/
|
||||
@@ -1545,7 +1556,7 @@ class MergeQuery extends Query implements QueryConditionInterface {
|
||||
$this->condition->notExists($select);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements QueryConditionInterface::conditions().
|
||||
*/
|
||||
@@ -1595,55 +1606,43 @@ class MergeQuery extends Query implements QueryConditionInterface {
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
// Wrap multiple queries in a transaction, if the database supports it.
|
||||
$transaction = $this->connection->startTransaction();
|
||||
try {
|
||||
if (!count($this->condition)) {
|
||||
throw new InvalidMergeQueryException(t('Invalid merge query: no conditions'));
|
||||
if (!count($this->condition)) {
|
||||
throw new InvalidMergeQueryException(t('Invalid merge query: no conditions'));
|
||||
}
|
||||
$select = $this->connection->select($this->conditionTable)
|
||||
->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)
|
||||
->condition($this->condition)
|
||||
->forUpdate();
|
||||
$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 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;
|
||||
}
|
||||
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) {
|
||||
// Something really wrong happened here, bubble up the exception to the
|
||||
// caller.
|
||||
$transaction->rollback();
|
||||
throw $e;
|
||||
}
|
||||
// Transaction commits here where $transaction looses scope.
|
||||
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 self::STATUS_UPDATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1762,14 +1761,14 @@ class DatabaseCondition implements QueryConditionInterface, Countable {
|
||||
public function exists(SelectQueryInterface $select) {
|
||||
return $this->condition('', $select, 'EXISTS');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements QueryConditionInterface::notExists().
|
||||
*/
|
||||
public function notExists(SelectQueryInterface $select) {
|
||||
return $this->condition('', $select, 'NOT EXISTS');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements QueryConditionInterface::conditions().
|
||||
*/
|
||||
|
||||
@@ -596,7 +596,7 @@ class SelectQueryExtender implements SelectQueryInterface {
|
||||
|
||||
public function hasAnyTag() {
|
||||
$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) {
|
||||
|
||||
@@ -250,7 +250,7 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
|
||||
$prefixes[$tablename] = '';
|
||||
$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;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,8 @@ class InsertQuery_sqlite extends InsertQuery {
|
||||
// If we're selecting from a SelectQuery, finish building the query and
|
||||
// pass it back, as any remaining options are irrelevant.
|
||||
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) . ')';
|
||||
|
||||
@@ -13,14 +13,6 @@
|
||||
*/
|
||||
interface DrupalEntityControllerInterface {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param $entityType
|
||||
* The entity type for which the instance is created.
|
||||
*/
|
||||
public function __construct($entityType);
|
||||
|
||||
/**
|
||||
* Resets the internal, static entity cache.
|
||||
*
|
||||
@@ -119,6 +111,9 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
|
||||
|
||||
/**
|
||||
* Constructor: sets basic variables.
|
||||
*
|
||||
* @param $entityType
|
||||
* The entity type for which the instance is created.
|
||||
*/
|
||||
public function __construct($entityType) {
|
||||
$this->entityType = $entityType;
|
||||
@@ -365,9 +360,23 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
|
||||
// This ensures the same behavior whether loading from memory or database.
|
||||
if ($conditions) {
|
||||
foreach ($entities as $entity) {
|
||||
$entity_values = (array) $entity;
|
||||
if (array_diff_assoc($conditions, $entity_values)) {
|
||||
unset($entities[$entity->{$this->idKey}]);
|
||||
// Iterate over all conditions and compare them to the entity
|
||||
// properties. We cannot use array_diff_assoc() here since the
|
||||
// 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.
|
||||
*
|
||||
*
|
||||
* Note that entities with empty field values will be excluded from the
|
||||
* EntityFieldQuery results when using this method.
|
||||
*
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Maps PHP error constants to watchdog severity levels.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
@@ -169,7 +169,7 @@ function error_displayable($error = NULL) {
|
||||
* TRUE if the error is fatal.
|
||||
*/
|
||||
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().
|
||||
if ($fatal && (drupal_get_bootstrap_phase() != DRUPAL_BOOTSTRAP_FULL)) {
|
||||
unset($GLOBALS['theme']);
|
||||
|
||||
@@ -470,8 +470,11 @@ function file_ensure_htaccess() {
|
||||
* @param $private
|
||||
* FALSE indicates that $directory should be an open and public 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)) {
|
||||
$directory = file_stream_wrapper_uri_normalize($directory);
|
||||
}
|
||||
@@ -480,19 +483,12 @@ function file_create_htaccess($directory, $private = TRUE) {
|
||||
}
|
||||
$htaccess_path = $directory . '/.htaccess';
|
||||
|
||||
if (file_exists($htaccess_path)) {
|
||||
if (file_exists($htaccess_path) && !$force_overwrite) {
|
||||
// Short circuit if the .htaccess file already exists.
|
||||
return;
|
||||
}
|
||||
|
||||
if ($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";
|
||||
}
|
||||
$htaccess_lines = file_htaccess_lines($private);
|
||||
|
||||
// Write the .htaccess file.
|
||||
if (file_put_contents($htaccess_path, $htaccess_lines)) {
|
||||
@@ -504,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.
|
||||
*
|
||||
@@ -586,7 +621,11 @@ function file_save(stdClass $file) {
|
||||
module_invoke_all('entity_update', $file, 'file');
|
||||
}
|
||||
|
||||
// Clear internal properties.
|
||||
unset($file->original);
|
||||
// Clear the static loading cache.
|
||||
entity_get_controller('file')->resetCache(array($file->fid));
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
@@ -719,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
|
||||
* performs like an advanced version of copy().
|
||||
* - 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,
|
||||
* 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
|
||||
* temporary file, the resulting file will also be a temporary file. See
|
||||
* file_save_upload() for details on temporary files.
|
||||
@@ -817,10 +857,11 @@ function file_valid_uri($uri) {
|
||||
* This is a powerful function that in many ways performs like an advanced
|
||||
* version of copy().
|
||||
* - 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,
|
||||
* 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
|
||||
* wrappers. This can occur because PHP's copy() function does not properly
|
||||
* support streams if safe_mode or open_basedir are enabled. See
|
||||
@@ -1108,7 +1149,7 @@ function file_munge_filename($filename, $extensions, $alerts = TRUE) {
|
||||
|
||||
// Allow potentially insecure uploads for very savvy users and admin
|
||||
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);
|
||||
|
||||
$whitelist = array_unique(explode(' ', trim($extensions)));
|
||||
@@ -1256,6 +1297,7 @@ function file_delete(stdClass $file, $force = FALSE) {
|
||||
if (file_unmanaged_delete($file->uri)) {
|
||||
db_delete('file_managed')->condition('fid', $file->fid)->execute();
|
||||
db_delete('file_usage')->condition('fid', $file->fid)->execute();
|
||||
entity_get_controller('file')->resetCache();
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
@@ -1365,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,
|
||||
* assign the status and use file_save() to save the changes.
|
||||
*
|
||||
* @param $source
|
||||
* A string specifying the filepath or URI of the uploaded file to save.
|
||||
* @param $form_field_name
|
||||
* A string that is the associative array key of the upload form element in
|
||||
* the form array.
|
||||
* @param $validators
|
||||
* An optional, associative array of callback functions used to validate the
|
||||
* file. See file_validate() for a full discussion of the array format.
|
||||
@@ -1377,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
|
||||
* at all).
|
||||
* @param $destination
|
||||
* A string containing the URI $source should be copied to.
|
||||
* This must be a stream wrapper URI. If this value is omitted, Drupal's
|
||||
* temporary files scheme will be used ("temporary://").
|
||||
* A string containing the URI that the file should be copied to. This must
|
||||
* be a stream wrapper URI. If this value is omitted, Drupal's temporary
|
||||
* files scheme will be used ("temporary://").
|
||||
* @param $replace
|
||||
* Replace behavior when the destination file already exists:
|
||||
* - FILE_EXISTS_REPLACE: Replace the existing file.
|
||||
@@ -1397,45 +1440,45 @@ function file_space_used($uid = NULL, $status = FILE_STATUS_PERMANENT) {
|
||||
* - source: Path to the file before it is moved.
|
||||
* - 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;
|
||||
static $upload_cache;
|
||||
|
||||
// Return cached objects without processing since the file will have
|
||||
// already been processed and the paths in _FILES will be invalid.
|
||||
if (isset($upload_cache[$source])) {
|
||||
return $upload_cache[$source];
|
||||
if (isset($upload_cache[$form_field_name])) {
|
||||
return $upload_cache[$form_field_name];
|
||||
}
|
||||
|
||||
// Make sure there's an upload to process.
|
||||
if (empty($_FILES['files']['name'][$source])) {
|
||||
if (empty($_FILES['files']['name'][$form_field_name])) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Check for file upload errors and return FALSE if a lower level system
|
||||
// error occurred. For a complete list of errors:
|
||||
// See http://php.net/manual/en/features.file-upload.errors.php.
|
||||
switch ($_FILES['files']['error'][$source]) {
|
||||
// See http://php.net/manual/features.file-upload.errors.php.
|
||||
switch ($_FILES['files']['error'][$form_field_name]) {
|
||||
case UPLOAD_ERR_INI_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;
|
||||
|
||||
case UPLOAD_ERR_PARTIAL:
|
||||
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;
|
||||
|
||||
case UPLOAD_ERR_OK:
|
||||
// Final check that this is a valid upload, if it isn't, use the
|
||||
// default error handler.
|
||||
if (is_uploaded_file($_FILES['files']['tmp_name'][$source])) {
|
||||
if (is_uploaded_file($_FILES['files']['tmp_name'][$form_field_name])) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Unknown error
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1443,10 +1486,10 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
|
||||
$file = new stdClass();
|
||||
$file->uid = $user->uid;
|
||||
$file->status = 0;
|
||||
$file->filename = trim(drupal_basename($_FILES['files']['name'][$source]), '.');
|
||||
$file->uri = $_FILES['files']['tmp_name'][$source];
|
||||
$file->filename = trim(drupal_basename($_FILES['files']['name'][$form_field_name]), '.');
|
||||
$file->uri = $_FILES['files']['tmp_name'][$form_field_name];
|
||||
$file->filemime = file_get_mimetype($file->filename);
|
||||
$file->filesize = $_FILES['files']['size'][$source];
|
||||
$file->filesize = $_FILES['files']['size'][$form_field_name];
|
||||
|
||||
$extensions = '';
|
||||
if (isset($validators['file_validate_extensions'])) {
|
||||
@@ -1503,7 +1546,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$file->source = $source;
|
||||
$file->source = $form_field_name;
|
||||
// A URI may already have a trailing slash or look like "public://".
|
||||
if (substr($destination, -1) != '/') {
|
||||
$destination .= '/';
|
||||
@@ -1512,7 +1555,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
|
||||
// If file_destination() returns FALSE then $replace == FILE_EXISTS_ERROR and
|
||||
// there's an existing file so we need to bail.
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1531,7 +1574,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
|
||||
else {
|
||||
$message .= ' ' . array_pop($errors);
|
||||
}
|
||||
form_set_error($source, $message);
|
||||
form_set_error($form_field_name, $message);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1539,8 +1582,8 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
|
||||
// directory. This overcomes open_basedir restrictions for future file
|
||||
// operations.
|
||||
$file->uri = $file->destination;
|
||||
if (!drupal_move_uploaded_file($_FILES['files']['tmp_name'][$source], $file->uri)) {
|
||||
form_set_error($source, t('File upload error. Could not move uploaded file.'));
|
||||
if (!drupal_move_uploaded_file($_FILES['files']['tmp_name'][$form_field_name], $file->uri)) {
|
||||
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));
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1560,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 ($file = file_save($file)) {
|
||||
// Add file to the cache.
|
||||
$upload_cache[$source] = $file;
|
||||
$upload_cache[$form_field_name] = $file;
|
||||
return $file;
|
||||
}
|
||||
return FALSE;
|
||||
@@ -2177,7 +2220,7 @@ function drupal_chmod($uri, $mode = NULL) {
|
||||
* @param $uri
|
||||
* A URI or pathname.
|
||||
* @param $context
|
||||
* Refer to http://php.net/manual/en/ref.stream.php
|
||||
* Refer to http://php.net/manual/ref.stream.php
|
||||
*
|
||||
* @return
|
||||
* Boolean TRUE on success, or FALSE on failure.
|
||||
@@ -2199,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
|
||||
* use 7.x stream wrappers. However, it assumes that every URI may be 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.
|
||||
* The use of drupal_realpath() is discouraged, because it does not work for
|
||||
* remote URIs. Except in rare cases, URIs should not be manually resolved.
|
||||
*
|
||||
* 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
|
||||
* that is incompatible with stream URIs.
|
||||
*
|
||||
* @param $uri
|
||||
* A stream wrapper URI or a filesystem path, possibly including one or more
|
||||
* symbolic links.
|
||||
* @param string $uri
|
||||
* A stream wrapper URI or a filepath, possibly including one or more symbolic
|
||||
* links.
|
||||
*
|
||||
* @return
|
||||
* The absolute local filesystem path (with no symbolic links), or FALSE on
|
||||
* failure.
|
||||
*
|
||||
* @todo This function is deprecated, and should be removed wherever possible.
|
||||
* @return string|false
|
||||
* The absolute local filepath (with no symbolic links), or FALSE on failure.
|
||||
*
|
||||
* @see DrupalStreamWrapperInterface::realpath()
|
||||
* @see http://php.net/manual/function.realpath.php
|
||||
@@ -2318,7 +2353,7 @@ function drupal_basename($uri, $suffix = NULL) {
|
||||
* @param $recursive
|
||||
* Default to FALSE.
|
||||
* @param $context
|
||||
* Refer to http://php.net/manual/en/ref.stream.php
|
||||
* Refer to http://php.net/manual/ref.stream.php
|
||||
*
|
||||
* @return
|
||||
* Boolean TRUE on success, or FALSE on failure.
|
||||
@@ -2349,7 +2384,7 @@ function drupal_mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) {
|
||||
* @param $uri
|
||||
* A URI or pathname.
|
||||
* @param $context
|
||||
* Refer to http://php.net/manual/en/ref.stream.php
|
||||
* Refer to http://php.net/manual/ref.stream.php
|
||||
*
|
||||
* @return
|
||||
* Boolean TRUE on success, or FALSE on failure.
|
||||
|
||||
@@ -82,11 +82,11 @@ class FileTransferFTPExtension extends FileTransferFTP implements FileTransferCh
|
||||
if (!$list) {
|
||||
$list = array();
|
||||
}
|
||||
foreach ($list as $item){
|
||||
foreach ($list as $item) {
|
||||
if ($item == '.' || $item == '..') {
|
||||
continue;
|
||||
}
|
||||
if (@ftp_chdir($this->connection, $item)){
|
||||
if (@ftp_chdir($this->connection, $item)) {
|
||||
ftp_cdup($this->connection);
|
||||
$this->removeDirectory(ftp_pwd($this->connection) . '/' . $item);
|
||||
}
|
||||
@@ -122,7 +122,7 @@ class FileTransferFTPExtension extends FileTransferFTP implements FileTransferCh
|
||||
|
||||
function chmodJailed($path, $mode, $recursive) {
|
||||
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) {
|
||||
$filelist = @ftp_nlist($this->connection, $path);
|
||||
|
||||
@@ -15,10 +15,9 @@
|
||||
* reference the form builder function using \@see. For examples, of this see
|
||||
* system_modules_uninstall() or user_pass(), the latter of which has the
|
||||
* following in its doxygen documentation:
|
||||
*
|
||||
* \@ingroup forms
|
||||
* \@see user_pass_validate().
|
||||
* \@see user_pass_submit().
|
||||
* - \@ingroup forms
|
||||
* - \@see user_pass_validate()
|
||||
* - \@see user_pass_submit()
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
@@ -168,6 +167,12 @@ function drupal_get_form($form_id) {
|
||||
* processed.
|
||||
* - base_form_id: Identification for a base form, as declared in a
|
||||
* 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
|
||||
* drupal_rebuild_form().
|
||||
* - 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.
|
||||
* - programmed: If TRUE, the form was submitted programmatically, usually
|
||||
* 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.
|
||||
* 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
|
||||
@@ -402,6 +413,7 @@ function form_state_defaults() {
|
||||
'submitted' => FALSE,
|
||||
'executed' => FALSE,
|
||||
'programmed' => FALSE,
|
||||
'programmed_bypass_access_check' => TRUE,
|
||||
'cache'=> FALSE,
|
||||
'method' => 'post',
|
||||
'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);
|
||||
|
||||
// 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
|
||||
// manually update the hidden 'build_id' input element.
|
||||
// RIA clients), or if the form already had a new build ID regenerated when it
|
||||
// was retrieved from the form cache, reuse the existing #build_id.
|
||||
// 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
|
||||
// earlier build, make changes, and re-submit.
|
||||
// @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'];
|
||||
if ($old_form_is_mutable_copy) {
|
||||
$form['#build_id_old'] = $old_form['#build_id_old'];
|
||||
}
|
||||
}
|
||||
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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -528,15 +557,28 @@ function form_set_cache($form_build_id, $form, $form_state) {
|
||||
// 6 hours cache life time for forms should be plenty.
|
||||
$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.
|
||||
if (isset($form)) {
|
||||
if ($GLOBALS['user']->uid) {
|
||||
$form['#cache_token'] = drupal_get_token();
|
||||
}
|
||||
unset($form['#build_id_old']);
|
||||
cache_set('form_' . $form_build_id, $form, 'cache_form', REQUEST_TIME + $expire);
|
||||
}
|
||||
|
||||
// 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()))) {
|
||||
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
|
||||
// the form builder callbacks can be loaded when the form is being rebuilt
|
||||
// from cache on a different path (such as 'system/ajax'). See
|
||||
// form_get_cache().
|
||||
// $menu_get_item() is not available during installation.
|
||||
// form_get_cache(). Don't do this in maintenance mode as Drupal may not be
|
||||
// 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')) {
|
||||
$item = menu_get_item();
|
||||
if (!empty($item['include_file'])) {
|
||||
@@ -976,7 +1019,7 @@ function drupal_prepare_form($form_id, &$form, &$form_state) {
|
||||
// @see drupal_build_form()
|
||||
// @see drupal_rebuild_form()
|
||||
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(
|
||||
'#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.
|
||||
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
|
||||
// submitted with drupal_form_submit() may bypass access restriction and be
|
||||
// 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.
|
||||
if (!isset($element['#value']) && !array_key_exists('#value', $element)) {
|
||||
@@ -3051,8 +3100,7 @@ function form_process_radios($element) {
|
||||
* @param $variables
|
||||
* An associative array containing:
|
||||
* - element: An associative array containing the properties of the element.
|
||||
* Properties used: #title, #value, #return_value, #description, #required,
|
||||
* #attributes, #checked.
|
||||
* Properties used: #id, #name, #attributes, #checked, #return_value.
|
||||
*
|
||||
* @ingroup themeable
|
||||
*/
|
||||
@@ -4244,7 +4292,7 @@ function element_validate_number($element, &$form_state) {
|
||||
* returns any user input in the 'results' or 'message' keys of $context,
|
||||
* it must also sanitize them first.
|
||||
*
|
||||
* Sample batch operations:
|
||||
* Sample callback_batch_operation():
|
||||
* @code
|
||||
* // Simple and artificial: load a node of a given type for a given user
|
||||
* function my_function_1($uid, $type, &$context) {
|
||||
@@ -4296,7 +4344,7 @@ function element_validate_number($element, &$form_state) {
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* Sample 'finished' callback:
|
||||
* Sample callback_batch_finished():
|
||||
* @code
|
||||
* function batch_test_finished($success, $results, $operations) {
|
||||
* // The 'success' parameter means no fatal PHP errors were detected. All
|
||||
@@ -4335,12 +4383,14 @@ function element_validate_number($element, &$form_state) {
|
||||
* @param $batch_definition
|
||||
* An associative array defining the batch, with the following elements (all
|
||||
* 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:
|
||||
* @code
|
||||
* array(
|
||||
* array('my_function_1', array($arg1)),
|
||||
* array('my_function_2', array($arg2_1, $arg2_2)),
|
||||
* array('callback_batch_operation_1', array($arg1)),
|
||||
* array('callback_batch_operation_2', array($arg2_1, $arg2_2)),
|
||||
* )
|
||||
* @endcode
|
||||
* - title: A safe, translated string to use as the title for the progress
|
||||
@@ -4352,10 +4402,10 @@ function element_validate_number($element, &$form_state) {
|
||||
* @elapsed. Defaults to t('Completed @current of @total.').
|
||||
* - error_message: Message displayed if an error occurred while processing
|
||||
* the batch. Defaults to t('An error has occurred.').
|
||||
* - finished: Name of a function to be executed after the batch has
|
||||
* completed. This should be used to perform any result massaging that may
|
||||
* be needed, and possibly save data in $_SESSION for display after final
|
||||
* page redirection.
|
||||
* - finished: Name of an implementation of callback_batch_finished(). This is
|
||||
* executed after the batch has completed. This should be used to perform
|
||||
* any result massaging that may be needed, and possibly save data in
|
||||
* $_SESSION for display after final page redirection.
|
||||
* - file: Path to the file containing the definitions of the 'operations' and
|
||||
* '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
|
||||
|
||||
@@ -692,6 +692,21 @@ function install_full_redirect_url($install_state) {
|
||||
*/
|
||||
function install_display_output($output, $install_state) {
|
||||
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
|
||||
// request has ended before tasks have even been started, so there is nothing
|
||||
// meaningful to show.
|
||||
@@ -766,6 +781,15 @@ function install_system_module(&$install_state) {
|
||||
// Install system.module.
|
||||
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
|
||||
// upcoming bootstrap step.
|
||||
module_enable(array('user'), FALSE);
|
||||
@@ -981,7 +1005,7 @@ function install_settings_form_submit($form, &$form_state) {
|
||||
'required' => TRUE,
|
||||
);
|
||||
$settings['drupal_hash_salt'] = array(
|
||||
'value' => drupal_hash_base64(drupal_random_bytes(55)),
|
||||
'value' => drupal_random_key(),
|
||||
'required' => TRUE,
|
||||
);
|
||||
drupal_rewrite_settings($settings);
|
||||
|
||||
@@ -741,20 +741,27 @@ function drupal_install_system() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstalls a given list of modules.
|
||||
* Uninstalls a given list of disabled modules.
|
||||
*
|
||||
* @param $module_list
|
||||
* The modules to uninstall.
|
||||
* @param $uninstall_dependents
|
||||
* If TRUE, the function will check that all modules which depend on the
|
||||
* passed-in module list either are already uninstalled or contained in 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.
|
||||
* @param array $module_list
|
||||
* The modules to uninstall. It is the caller's responsibility to ensure that
|
||||
* all modules in this list have already been disabled before this function
|
||||
* is called.
|
||||
* @param bool $uninstall_dependents
|
||||
* (optional) If TRUE, the function will check that all modules which depend
|
||||
* on the passed-in module list either are already uninstalled or contained in
|
||||
* 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
|
||||
* FALSE if one or more dependent modules are missing from the list, TRUE
|
||||
* otherwise.
|
||||
* @return bool
|
||||
* Returns TRUE if the operation succeeds or FALSE if it aborts due to an
|
||||
* 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) {
|
||||
if ($uninstall_dependents) {
|
||||
@@ -766,7 +773,7 @@ function drupal_uninstall_modules($module_list = array(), $uninstall_dependents
|
||||
$profile = drupal_get_profile();
|
||||
while (list($module) = each($module_list)) {
|
||||
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]);
|
||||
continue;
|
||||
}
|
||||
@@ -799,7 +806,7 @@ function drupal_uninstall_modules($module_list = array(), $uninstall_dependents
|
||||
}
|
||||
|
||||
if (!empty($module_list)) {
|
||||
// Call hook_module_uninstall to let other modules act
|
||||
// Let other modules react.
|
||||
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
|
||||
foreach ($args as $key => $value) {
|
||||
switch ($key[0]) {
|
||||
|
||||
@@ -53,6 +53,7 @@ function _country_get_predefined_list() {
|
||||
'BM' => $t('Bermuda'),
|
||||
'BN' => $t('Brunei'),
|
||||
'BO' => $t('Bolivia'),
|
||||
'BQ' => $t('Caribbean Netherlands'),
|
||||
'BR' => $t('Brazil'),
|
||||
'BS' => $t('Bahamas'),
|
||||
'BT' => $t('Bhutan'),
|
||||
@@ -74,8 +75,8 @@ function _country_get_predefined_list() {
|
||||
'CO' => $t('Colombia'),
|
||||
'CR' => $t('Costa Rica'),
|
||||
'CU' => $t('Cuba'),
|
||||
'CW' => $t('Curaçao'),
|
||||
'CV' => $t('Cape Verde'),
|
||||
'CW' => $t('Curaçao'),
|
||||
'CX' => $t('Christmas Island'),
|
||||
'CY' => $t('Cyprus'),
|
||||
'CZ' => $t('Czech Republic'),
|
||||
@@ -230,8 +231,10 @@ function _country_get_predefined_list() {
|
||||
'SN' => $t('Senegal'),
|
||||
'SO' => $t('Somalia'),
|
||||
'SR' => $t('Suriname'),
|
||||
'SS' => $t('South Sudan'),
|
||||
'ST' => $t('Sao Tome and Principe'),
|
||||
'SV' => $t('El Salvador'),
|
||||
'SX' => $t('Sint Maarten'),
|
||||
'SY' => $t('Syria'),
|
||||
'SZ' => $t('Swaziland'),
|
||||
'TC' => $t('Turks and Caicos Islands'),
|
||||
|
||||
@@ -78,7 +78,7 @@ define('LANGUAGE_NEGOTIATION_DEFAULT', 'language-default');
|
||||
* 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']['negotiation'] = 'mymodule_from_url';
|
||||
* $negotiation_info[LANGUAGE_NEGOTIATION_URL]['callbacks']['language'] = 'mymodule_from_url';
|
||||
* $negotiation_info[LANGUAGE_NEGOTIATION_URL]['file'] = drupal_get_path('module', 'mymodule') . '/mymodule.module';
|
||||
* }
|
||||
*
|
||||
@@ -94,7 +94,6 @@ define('LANGUAGE_NEGOTIATION_DEFAULT', 'language-default');
|
||||
* }
|
||||
* return $langcode;
|
||||
* }
|
||||
* ?>
|
||||
* @endcode
|
||||
*
|
||||
* For more information, see
|
||||
@@ -314,7 +313,7 @@ function language_negotiation_get_switch_links($type, $path) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any unused language negotation providers from the configuration.
|
||||
* Removes any unused language negotiation providers from the configuration.
|
||||
*/
|
||||
function language_negotiation_purge() {
|
||||
// Ensure that we are getting the defined language negotiation information. An
|
||||
|
||||
@@ -339,13 +339,13 @@ interface MailSystemInterface {
|
||||
*
|
||||
* We deliberately use LF rather than CRLF, see drupal_mail().
|
||||
*
|
||||
* @param $text
|
||||
* @param string $text
|
||||
* The plain text to process.
|
||||
* @param $indent (optional)
|
||||
* @param string $indent (optional)
|
||||
* A string to indent the text with. Only '>' characters are repeated on
|
||||
* subsequent wrapped lines. Others are replaced by spaces.
|
||||
*
|
||||
* @return
|
||||
* @return string
|
||||
* The content of the email as a string with formatting applied.
|
||||
*/
|
||||
function drupal_wrap_mail($text, $indent = '') {
|
||||
@@ -356,8 +356,9 @@ function drupal_wrap_mail($text, $indent = '') {
|
||||
$soft = strpos($clean_indent, ' ') === FALSE;
|
||||
// Check if the string has line breaks.
|
||||
if (strpos($text, "\n") !== FALSE) {
|
||||
// Remove trailing spaces to make existing breaks hard.
|
||||
$text = preg_replace('/ +\n/m', "\n", $text);
|
||||
// Remove trailing spaces to make existing breaks hard, but leave signature
|
||||
// marker untouched (RFC 3676, Section 4.3).
|
||||
$text = preg_replace('/(?(?<!^--) +\n| +\n)/m', "\n", $text);
|
||||
// Wrap each line at the needed width.
|
||||
$lines = explode("\n", $text);
|
||||
array_walk($lines, '_drupal_wrap_mail_line', array('soft' => $soft, 'length' => strlen($indent)));
|
||||
@@ -563,7 +564,7 @@ function drupal_html_to_text($string, $allowed_tags = NULL) {
|
||||
*/
|
||||
function _drupal_wrap_mail_line(&$line, $key, $values) {
|
||||
// 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.
|
||||
$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().
|
||||
*
|
||||
* @param $parts
|
||||
* An array of path parts, for the above example
|
||||
* An array of path parts; for the above example,
|
||||
* array('node', '12345', 'edit').
|
||||
*
|
||||
* @return
|
||||
@@ -430,7 +430,7 @@ function menu_set_item($path, $router_item) {
|
||||
* Gets a router item.
|
||||
*
|
||||
* @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.
|
||||
* @param $router_item
|
||||
* Internal use only.
|
||||
@@ -542,7 +542,7 @@ function menu_execute_active_handler($path = NULL, $deliver = TRUE) {
|
||||
* @param $item
|
||||
* A menu router or menu link item
|
||||
* @param $map
|
||||
* An array of path arguments (ex: array('node', '5'))
|
||||
* An array of path arguments; for example, array('node', '5').
|
||||
*
|
||||
* @return
|
||||
* Returns TRUE for success, FALSE if an object cannot be loaded.
|
||||
@@ -612,7 +612,7 @@ function _menu_load_objects(&$item, &$map) {
|
||||
* @param $item
|
||||
* A menu router or menu link item
|
||||
* @param $map
|
||||
* An array of path arguments (ex: array('node', '5'))
|
||||
* An array of path arguments; for example, array('node', '5').
|
||||
*
|
||||
* @return
|
||||
* $item['access'] becomes TRUE if the item is accessible, FALSE otherwise.
|
||||
@@ -738,7 +738,7 @@ function _menu_item_localize(&$item, $map, $link_translate = FALSE) {
|
||||
* @param $router_item
|
||||
* A menu router item
|
||||
* @param $map
|
||||
* An array of path arguments (ex: array('node', '5'))
|
||||
* An array of path arguments; for example, array('node', '5').
|
||||
* @param $to_arg
|
||||
* Execute $item['to_arg_functions'] or not. Use only if you want to render a
|
||||
* path from the menu table, for example tabs.
|
||||
@@ -801,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.
|
||||
*
|
||||
* @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
|
||||
* 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()
|
||||
*/
|
||||
@@ -1000,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:
|
||||
* - expanded: The menu item is showing its submenu.
|
||||
@@ -1926,13 +1926,21 @@ function menu_local_tasks($level = 0) {
|
||||
}
|
||||
|
||||
// Get all tabs (also known as local tasks) and the root page.
|
||||
$result = db_select('menu_router', NULL, array('fetch' => PDO::FETCH_ASSOC))
|
||||
->fields('menu_router')
|
||||
->condition('tab_root', $router_item['tab_root'])
|
||||
->condition('context', MENU_CONTEXT_INLINE, '<>')
|
||||
->orderBy('weight')
|
||||
->orderBy('title')
|
||||
->execute();
|
||||
$cid = 'local_tasks:' . $router_item['tab_root'];
|
||||
if ($cache = cache_get($cid, 'cache_menu')) {
|
||||
$result = $cache->data;
|
||||
}
|
||||
else {
|
||||
$result = db_select('menu_router', NULL, array('fetch' => PDO::FETCH_ASSOC))
|
||||
->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'];
|
||||
$children = array();
|
||||
$tasks = array();
|
||||
@@ -2139,7 +2147,7 @@ function menu_local_tasks($level = 0) {
|
||||
* example 'node' or 'admin/structure/block/manage'.
|
||||
* @param $args
|
||||
* 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.
|
||||
*
|
||||
* @return
|
||||
@@ -2430,7 +2438,7 @@ function menu_set_active_trail($new_trail = NULL) {
|
||||
* Looks up the preferred menu link for a given system 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/%').
|
||||
* @param $selected_menu
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
@@ -803,10 +834,7 @@ function module_hook_info() {
|
||||
*/
|
||||
function module_implements_write_cache() {
|
||||
$implementations = &drupal_static('module_implements');
|
||||
// Check whether we need to write the cache. We do not want to cache hooks
|
||||
// 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')) {
|
||||
if (isset($implementations['#write_cache'])) {
|
||||
unset($implementations['#write_cache']);
|
||||
cache_set('module_implements', $implementations, 'cache_bootstrap');
|
||||
}
|
||||
@@ -815,6 +843,9 @@ function module_implements_write_cache() {
|
||||
/**
|
||||
* 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
|
||||
* The name of the module (without the .module extension).
|
||||
* @param $hook
|
||||
@@ -824,6 +855,8 @@ function module_implements_write_cache() {
|
||||
*
|
||||
* @return
|
||||
* The return value of the hook implementation.
|
||||
*
|
||||
* @see drupal_alter()
|
||||
*/
|
||||
function module_invoke($module, $hook) {
|
||||
$args = func_get_args();
|
||||
@@ -837,6 +870,9 @@ function module_invoke($module, $hook) {
|
||||
/**
|
||||
* 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
|
||||
* The name of the hook to invoke.
|
||||
* @param ...
|
||||
@@ -845,6 +881,8 @@ function module_invoke($module, $hook) {
|
||||
* @return
|
||||
* An array of return values of the hook implementations. If modules return
|
||||
* arrays from their implementations, those are merged into one array.
|
||||
*
|
||||
* @see drupal_alter()
|
||||
*/
|
||||
function module_invoke_all($hook) {
|
||||
$args = func_get_args();
|
||||
|
||||
@@ -560,8 +560,8 @@ function drupal_valid_path($path, $dynamic_allowed = FALSE) {
|
||||
elseif ($dynamic_allowed && preg_match('/\/\%/', $path)) {
|
||||
// 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()) {
|
||||
$item['link_path'] = $form_item['link_path'];
|
||||
$item['link_title'] = $form_item['link_title'];
|
||||
$item['link_path'] = $item['path'];
|
||||
$item['link_title'] = $item['title'];
|
||||
$item['external'] = FALSE;
|
||||
$item['options'] = '';
|
||||
_menu_link_translate($item);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* @{
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
// anonymous users than are generated in drupal_session_regenerate() when
|
||||
// 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)) {
|
||||
$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;
|
||||
}
|
||||
}
|
||||
@@ -360,7 +360,7 @@ function drupal_session_regenerate() {
|
||||
$old_insecure_session_id = $_COOKIE[$insecure_session_name];
|
||||
}
|
||||
$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
|
||||
// $params['lifetime'] seconds from the current request. If it is not set,
|
||||
// it will expire when the browser is closed.
|
||||
@@ -372,7 +372,7 @@ function drupal_session_regenerate() {
|
||||
if (drupal_session_started()) {
|
||||
$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)) {
|
||||
$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.
|
||||
*
|
||||
* @see http://www.php.net/manual/en/class.streamwrapper.php
|
||||
* @see http://www.php.net/manual/class.streamwrapper.php
|
||||
*/
|
||||
interface StreamWrapperInterface {
|
||||
public function stream_open($uri, $mode, $options, &$opened_url);
|
||||
@@ -401,7 +401,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* 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) {
|
||||
$this->uri = $uri;
|
||||
@@ -429,7 +429,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* 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) {
|
||||
if (in_array($operation, array(LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB))) {
|
||||
@@ -448,7 +448,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* 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) {
|
||||
return fread($this->handle, $count);
|
||||
@@ -463,7 +463,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* 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) {
|
||||
return fwrite($this->handle, $data);
|
||||
@@ -475,7 +475,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* 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() {
|
||||
return feof($this->handle);
|
||||
@@ -492,7 +492,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* 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) {
|
||||
// fseek returns 0 on success and -1 on a failure.
|
||||
@@ -506,7 +506,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* 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() {
|
||||
return fflush($this->handle);
|
||||
@@ -518,7 +518,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* 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() {
|
||||
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()
|
||||
* 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() {
|
||||
return fstat($this->handle);
|
||||
@@ -543,7 +543,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* 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() {
|
||||
return fclose($this->handle);
|
||||
@@ -558,7 +558,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* 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) {
|
||||
$this->uri = $uri;
|
||||
@@ -576,7 +576,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* 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) {
|
||||
return rename($this->getLocalPath($from_uri), $this->getLocalPath($to_uri));
|
||||
@@ -622,7 +622,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* 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) {
|
||||
$this->uri = $uri;
|
||||
@@ -654,7 +654,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* 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) {
|
||||
$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()
|
||||
* 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) {
|
||||
$this->uri = $uri;
|
||||
@@ -704,7 +704,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* 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) {
|
||||
$this->uri = $uri;
|
||||
@@ -719,7 +719,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* 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() {
|
||||
return readdir($this->handle);
|
||||
@@ -731,7 +731,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* 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() {
|
||||
rewinddir($this->handle);
|
||||
@@ -747,7 +747,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
||||
* @return
|
||||
* 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() {
|
||||
closedir($this->handle);
|
||||
@@ -788,8 +788,6 @@ class DrupalPublicStreamWrapper extends DrupalLocalStreamWrapper {
|
||||
*
|
||||
* Provides support for storing privately accessible files with the Drupal file
|
||||
* interface.
|
||||
*
|
||||
* Extends DrupalPublicStreamWrapper.
|
||||
*/
|
||||
class DrupalPrivateStreamWrapper extends DrupalLocalStreamWrapper {
|
||||
/**
|
||||
|
||||
@@ -508,7 +508,7 @@ class ThemeRegistry Extends DrupalCacheArray {
|
||||
* themes/bartik.
|
||||
*
|
||||
* @see theme()
|
||||
* @see _theme_process_registry()
|
||||
* @see _theme_build_registry()
|
||||
* @see hook_theme()
|
||||
* @see list_themes()
|
||||
*/
|
||||
@@ -869,11 +869,18 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) {
|
||||
/**
|
||||
* Generates themed output.
|
||||
*
|
||||
* All requests for themed output must go through this function. It examines
|
||||
* the request and routes it to the appropriate
|
||||
* All requests for themed output must go through this function (however,
|
||||
* 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
|
||||
* 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
|
||||
* hook. For instance, to theme a taxonomy term, the theme hook name is
|
||||
* 'taxonomy_term'. Modules register theme hooks within a hook_theme()
|
||||
@@ -885,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
|
||||
* 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()
|
||||
* implementation, but it is more common for themes to override default
|
||||
* implementations provided by modules than to register entirely new theme
|
||||
@@ -897,6 +905,7 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) {
|
||||
* rendering engine, it overrides the default implementation of the 'page' theme
|
||||
* 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
|
||||
* before the template file is invoked, to modify the $variables array. These
|
||||
* fall into the "preprocessing" phase and the "processing" phase, and are
|
||||
@@ -945,12 +954,14 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) {
|
||||
* - THEME_process_HOOK(&$variables): Allows the theme to process the
|
||||
* 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
|
||||
* and process functions (the ones ending in _HOOK) are called from the
|
||||
* list above. This is because theme hooks with function implementations
|
||||
* need to be fast, and calling the non-theme-hook-specific preprocess and
|
||||
* 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
|
||||
* 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,
|
||||
@@ -992,6 +1003,7 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) {
|
||||
* @return
|
||||
* An HTML string representing the themed output.
|
||||
*
|
||||
* @see drupal_render()
|
||||
* @see themeable
|
||||
* @see hook_theme()
|
||||
* @see template_preprocess()
|
||||
@@ -1814,7 +1826,9 @@ function theme_breadcrumb($variables) {
|
||||
* - "data": The localized title of the table column.
|
||||
* - "field": The database field represented in the table column (required
|
||||
* 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
|
||||
* cell.
|
||||
* - rows: An array of table rows. Every row is an array of cells, or an
|
||||
@@ -1973,25 +1987,24 @@ function theme_table($variables) {
|
||||
$flip = array('even' => 'odd', 'odd' => 'even');
|
||||
$class = 'even';
|
||||
foreach ($rows as $number => $row) {
|
||||
$attributes = array();
|
||||
|
||||
// Check if we're dealing with a simple or complex row
|
||||
if (isset($row['data'])) {
|
||||
foreach ($row as $key => $value) {
|
||||
if ($key == 'data') {
|
||||
$cells = $value;
|
||||
}
|
||||
else {
|
||||
$attributes[$key] = $value;
|
||||
}
|
||||
}
|
||||
$cells = $row['data'];
|
||||
$no_striping = isset($row['no_striping']) ? $row['no_striping'] : FALSE;
|
||||
|
||||
// Set the attributes array and exclude 'data' and 'no_striping'.
|
||||
$attributes = $row;
|
||||
unset($attributes['data']);
|
||||
unset($attributes['no_striping']);
|
||||
}
|
||||
else {
|
||||
$cells = $row;
|
||||
$attributes = array();
|
||||
$no_striping = FALSE;
|
||||
}
|
||||
if (count($cells)) {
|
||||
// Add odd/even class
|
||||
if (empty($row['no_striping'])) {
|
||||
if (!$no_striping) {
|
||||
$class = $flip[$class];
|
||||
$attributes['class'][] = $class;
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Initiates a browser-based installation of Drupal.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Defines the root directory of the Drupal installation.
|
||||
*/
|
||||
define('DRUPAL_ROOT', getcwd());
|
||||
|
||||
/**
|
||||
* Global flag to indicate the 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 |
@@ -616,6 +616,13 @@ Drupal.ajax.prototype.commands = {
|
||||
.removeClass('odd even')
|
||||
.filter(':even').addClass('odd').end()
|
||||
.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) {
|
||||
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) {
|
||||
// Select item if the right key or mousebutton was pressed.
|
||||
if (this.selected && ((keycode && keycode != 46 && keycode != 8 && keycode != 27) || !keycode)) {
|
||||
this.input.value = $(this.selected).data('autocompleteValue');
|
||||
this.select(this.selected);
|
||||
}
|
||||
// Hide popup.
|
||||
var popup = this.popup;
|
||||
@@ -220,7 +221,7 @@ Drupal.jsAC.prototype.found = function (matches) {
|
||||
for (key in matches) {
|
||||
$('<li></li>')
|
||||
.html($('<div></div>').html(matches[key]))
|
||||
.mousedown(function () { ac.select(this); })
|
||||
.mousedown(function () { ac.hidePopup(this); })
|
||||
.mouseover(function () { ac.highlight(this); })
|
||||
.mouseout(function () { ac.unhighlight(this); })
|
||||
.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 |