update core to 7.36
This commit is contained in:
parent
6de56c702c
commit
802ec0c6f3
154
CHANGELOG.txt
154
CHANGELOG.txt
@ -1,4 +1,158 @@
|
|||||||
|
|
||||||
|
Drupal 7.36, 2015-04-01
|
||||||
|
-----------------------
|
||||||
|
- Added a 'file_public_schema' variable which allows modules that define
|
||||||
|
publicly-accessible streams in hook_stream_wrappers() to bypass file download
|
||||||
|
access checks when processing managed file upload fields.
|
||||||
|
- Fixed a bug that caused database query tags not to be added to search-related
|
||||||
|
database queries under many circumstances, and which prevented the
|
||||||
|
corresponding hook_query_TAG_alter() implementations from being called.
|
||||||
|
- Fixed the "for" attribute on managed file upload field labels to improve
|
||||||
|
accessibility (minor markup change).
|
||||||
|
- Added a 'javascript_always_use_jquery' variable which can be set to FALSE by
|
||||||
|
sites that may not need jQuery loaded on all pages, and a 'requires_jquery'
|
||||||
|
option to drupal_add_js() which modules can set to FALSE when adding
|
||||||
|
JavaScript files that have no dependency on jQuery (API addition:
|
||||||
|
https://www.drupal.org/node/2462717).
|
||||||
|
- Fixed incorrect foreign keys in the User module's role_permission and
|
||||||
|
users_roles database tables.
|
||||||
|
- Changed permission descriptions throughout Drupal core to consistently link
|
||||||
|
to relevant administrative pages, regardless of whether the user viewing the
|
||||||
|
Permissions page can view the page being linked to (minor UI change).
|
||||||
|
- Fixed the drupal_add_region_content() function so that it actually adds
|
||||||
|
content to the page.
|
||||||
|
- Added an 'image_suppress_itok_output' variable to allow sites already using
|
||||||
|
the existing 'image_allow_insecure_derivatives' variable to also prevent
|
||||||
|
security tokens from appearing in image derivative URLs.
|
||||||
|
- Fixed double-escaping of theme names in the Block module administrative
|
||||||
|
interface (minor string change).
|
||||||
|
- Added basic support for Xdebug when running automated tests.
|
||||||
|
- Fixed a bug which caused previewing a node to remove elements from the node
|
||||||
|
being edited. With this fix, calling node_preview() will no longer modify the
|
||||||
|
passed-in node object (minor API change).
|
||||||
|
- Added a user_has_role() function to check whether a user has a particular
|
||||||
|
role (API addition: https://www.drupal.org/node/2462411).
|
||||||
|
- Fixed installation failures when an opcode cache is enabled.
|
||||||
|
- Fixed a bug in the Drupal 6 to Drupal 7 upgrade path which caused private
|
||||||
|
files to be inaccessible.
|
||||||
|
- Fixed a bug in the Drupal 6 to Drupal 7 upgrade path which caused user
|
||||||
|
pictures to be lost.
|
||||||
|
- Fixed missing language code in hook_field_attach_view_alter() when it is
|
||||||
|
invoked from field_view_field().
|
||||||
|
- Stopped sending ETag and Last-Modified headers for uncached page requests,
|
||||||
|
since they break caching for certain Varnish and Nginx configurations.
|
||||||
|
- Changed the Simpletest module to allow PSR-4 test classes to be used in
|
||||||
|
Drupal 7.
|
||||||
|
- Fixed a fatal error that occurred when using the Comment module's "Unpublish
|
||||||
|
comment containing keyword(s)" action.
|
||||||
|
- Changed the "lang" attribute on language links to "xml:lang" so it validates
|
||||||
|
as XHTML (minor markup change).
|
||||||
|
- Prevented the form API from allowing arrays to be submitted for various form
|
||||||
|
elements, such as textfields, textareas, and password fields (API change:
|
||||||
|
https://www.drupal.org/node/2462723).
|
||||||
|
- Fixed a bug in the Contact module which caused the global user object to have
|
||||||
|
the incorrect name and e-mail address during the remainder of the page
|
||||||
|
request after the contact form is submitted.
|
||||||
|
- Numerous small bug fixes.
|
||||||
|
- Numerous API documentation improvements.
|
||||||
|
- Additional automated test coverage.
|
||||||
|
|
||||||
|
Drupal 7.35, 2015-03-18
|
||||||
|
----------------------
|
||||||
|
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2015-001.
|
||||||
|
|
||||||
|
Drupal 7.34, 2014-11-19
|
||||||
|
----------------------
|
||||||
|
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2014-006.
|
||||||
|
|
||||||
|
Drupal 7.33, 2014-11-07
|
||||||
|
-----------------------
|
||||||
|
- Began storing the file modification time of each module and theme in the
|
||||||
|
{system} database table so that contributed modules can use it to identify
|
||||||
|
recently changed modules and themes (minor data structure change to the
|
||||||
|
return value of system_get_info() and other related functions).
|
||||||
|
- Added a "Did you mean?" feature to the run-tests.sh script for running
|
||||||
|
automated tests from the command line, to help developers who are attempting
|
||||||
|
to run a particular test class or group.
|
||||||
|
- Changed the date format used in various HTTP headers output by Drupal core
|
||||||
|
from RFC 1123 format to RFC 7231 format.
|
||||||
|
- Added a "block_cache_bypass_node_grants" variable to allow sites which have
|
||||||
|
node access modules enabled to use the block cache if desired (API addition).
|
||||||
|
- Made image derivative generation HTTP requests return a 404 error (rather
|
||||||
|
than a 500 error) when the source image does not exist.
|
||||||
|
- Fixed a bug which caused user pictures to be removed from the user object
|
||||||
|
after saving, and resulted in data loss if the user account was subsequently
|
||||||
|
re-saved.
|
||||||
|
- Fixed a bug in which field_has_data() did not return TRUE for fields that
|
||||||
|
only had data in older entity revisions, leading to loss of the field's data
|
||||||
|
when the field configuration was edited.
|
||||||
|
- Fixed a bug which caused the Ajax progress throbber to appear misaligned in
|
||||||
|
many situatons (minor styling change).
|
||||||
|
- Prevented the Bartik theme from lower-casing the "Permalink" link on
|
||||||
|
comments, for improved multilingual support (minor UI change).
|
||||||
|
- Added a "preferred_menu_links" tag to the database query that is used by
|
||||||
|
menu_link_get_preferred() to find the preferred menu link for a given path,
|
||||||
|
to make it easier to alter.
|
||||||
|
- Increased the maximum allowed length of block titles to 255 characters
|
||||||
|
(database schema change to the {block} table).
|
||||||
|
- Removed the Field module's field_modules_uninstalled() function, since it did
|
||||||
|
not do anything when it was invoked.
|
||||||
|
- Added a "theme_hook_original" variable to templates and theme functions and
|
||||||
|
an optional sitewide theme debug mode, to provide contextual information in
|
||||||
|
the page's HTML to theme developers. The theme debug mode is based on the one
|
||||||
|
used with Twig in Drupal 8 and can be accessed by setting the "theme_debug"
|
||||||
|
variable to TRUE (API addition).
|
||||||
|
- Added an entity_view_mode_prepare() API function to allow entity-defining
|
||||||
|
modules to properly invoke hook_entity_view_mode_alter(), and used it
|
||||||
|
throughout Drupal core to fix bugs with the invocation of that hook (API
|
||||||
|
change: https://www.drupal.org/node/2369141).
|
||||||
|
- Security improvement: Made the database API's orderBy() method sanitize the
|
||||||
|
sort direction ("ASC" or "DESC") for queries built with db_select(), so that
|
||||||
|
calling code does not have to.
|
||||||
|
- Changed the RDF module to consistently output RDF metadata for nodes and
|
||||||
|
comments near where the node is rendered in the HTML (minor markup and data
|
||||||
|
structure change).
|
||||||
|
- Added an HTML class to RDFa metatags throughout Drupal to prevent them from
|
||||||
|
accidentally affecting the site appearance (minor markup change).
|
||||||
|
- Fixed a bug in the Unicode requirements check which prevented installing
|
||||||
|
Drupal on PHP 5.6.
|
||||||
|
- Fixed a bug which caused drupal_get_bootstrap_phase() to abort the bootstrap
|
||||||
|
when called early in the page request.
|
||||||
|
- Renamed the "Search result" view mode to "Search result highlighting input"
|
||||||
|
to better reflect how it is used (UI change).
|
||||||
|
- Improved database queries generated by EntityFieldQuery in the case where
|
||||||
|
delta or language condition groups are used, to reduce the number of INNER
|
||||||
|
JOINs (this is a minor data structure change affecting code which implements
|
||||||
|
hook_query_alter() on these queries).
|
||||||
|
- Removed special-case behavior for file uploads which allowed user #1 to
|
||||||
|
bypass maximum file size and user quota limits.
|
||||||
|
- Numerous small bug fixes.
|
||||||
|
- Numerous API documentation improvements.
|
||||||
|
- Additional automated test coverage.
|
||||||
|
|
||||||
|
Drupal 7.32, 2014-10-15
|
||||||
|
----------------------
|
||||||
|
- Fixed security issues (SQL injection). See SA-CORE-2014-005.
|
||||||
|
|
||||||
|
Drupal 7.31, 2014-08-06
|
||||||
|
----------------------
|
||||||
|
- Fixed security issues (denial of service). See SA-CORE-2014-004.
|
||||||
|
|
||||||
|
Drupal 7.30, 2014-07-24
|
||||||
|
-----------------------
|
||||||
|
- Fixed a regression introduced in Drupal 7.29 that caused files or images
|
||||||
|
attached to taxonomy terms to be deleted when the taxonomy term was edited
|
||||||
|
and resaved (and other related bugs with contributed and custom modules).
|
||||||
|
- Added a warning on the permissions page to recommend restricting access to
|
||||||
|
the "View site reports" permission to trusted administrators. See
|
||||||
|
DRUPAL-PSA-2014-002.
|
||||||
|
- Numerous API documentation improvements.
|
||||||
|
- Additional automated test coverage.
|
||||||
|
|
||||||
|
Drupal 7.29, 2014-07-16
|
||||||
|
----------------------
|
||||||
|
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2014-003.
|
||||||
|
|
||||||
Drupal 7.28, 2014-05-08
|
Drupal 7.28, 2014-05-08
|
||||||
-----------------------
|
-----------------------
|
||||||
- Fixed a regression introduced in Drupal 7.27 that caused JavaScript to break
|
- Fixed a regression introduced in Drupal 7.27 that caused JavaScript to break
|
||||||
|
@ -27,7 +27,6 @@ Ajax system
|
|||||||
- Earl Miles 'merlinofchaos' http://drupal.org/user/26979
|
- Earl Miles 'merlinofchaos' http://drupal.org/user/26979
|
||||||
|
|
||||||
Base system
|
Base system
|
||||||
- Károly Négyesi 'chx' http://drupal.org/user/9446
|
|
||||||
- Damien Tournoud 'DamZ' http://drupal.org/user/22211
|
- Damien Tournoud 'DamZ' http://drupal.org/user/22211
|
||||||
- Moshe Weitzman 'moshe weitzman' http://drupal.org/user/23
|
- Moshe Weitzman 'moshe weitzman' http://drupal.org/user/23
|
||||||
|
|
||||||
@ -39,7 +38,6 @@ Cache system
|
|||||||
- Nathaniel Catchpole 'catch' http://drupal.org/user/35733
|
- Nathaniel Catchpole 'catch' http://drupal.org/user/35733
|
||||||
|
|
||||||
Cron system
|
Cron system
|
||||||
- Károly Négyesi 'chx' http://drupal.org/user/9446
|
|
||||||
- Derek Wright 'dww' http://drupal.org/user/46549
|
- Derek Wright 'dww' http://drupal.org/user/46549
|
||||||
|
|
||||||
Database system
|
Database system
|
||||||
@ -55,10 +53,8 @@ Database system
|
|||||||
|
|
||||||
- Sqlite driver
|
- Sqlite driver
|
||||||
- Damien Tournoud 'DamZ' http://drupal.org/user/22211
|
- Damien Tournoud 'DamZ' http://drupal.org/user/22211
|
||||||
- Károly Négyesi 'chx' http://drupal.org/user/9446
|
|
||||||
|
|
||||||
Database update system
|
Database update system
|
||||||
- Károly Négyesi 'chx' http://drupal.org/user/9446
|
|
||||||
- Ashok Modi 'BTMash' http://drupal.org/user/60422
|
- Ashok Modi 'BTMash' http://drupal.org/user/60422
|
||||||
|
|
||||||
Entity system
|
Entity system
|
||||||
@ -71,7 +67,6 @@ File system
|
|||||||
- Aaron Winborn 'aaron' http://drupal.org/user/33420
|
- Aaron Winborn 'aaron' http://drupal.org/user/33420
|
||||||
|
|
||||||
Form system
|
Form system
|
||||||
- Károly Négyesi 'chx' http://drupal.org/user/9446
|
|
||||||
- Alex Bronstein 'effulgentsia' http://drupal.org/user/78040
|
- Alex Bronstein 'effulgentsia' http://drupal.org/user/78040
|
||||||
- Wolfgang Ziegler 'fago' http://drupal.org/user/16747
|
- Wolfgang Ziegler 'fago' http://drupal.org/user/16747
|
||||||
- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
|
- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
|
||||||
@ -105,7 +100,6 @@ Markup
|
|||||||
|
|
||||||
Menu system
|
Menu system
|
||||||
- Peter Wolanin 'pwolanin' http://drupal.org/user/49851
|
- Peter Wolanin 'pwolanin' http://drupal.org/user/49851
|
||||||
- Károly Négyesi 'chx' http://drupal.org/user/9446
|
|
||||||
|
|
||||||
Path system
|
Path system
|
||||||
- Dave Reid 'davereid' http://drupal.org/user/53892
|
- Dave Reid 'davereid' http://drupal.org/user/53892
|
||||||
@ -139,9 +133,6 @@ Accessibility
|
|||||||
Documentation
|
Documentation
|
||||||
- Jennifer Hodgdon 'jhodgdon' http://drupal.org/user/155601
|
- Jennifer Hodgdon 'jhodgdon' http://drupal.org/user/155601
|
||||||
|
|
||||||
Security
|
|
||||||
- Greg Knaddison 'greggles' http://drupal.org/user/36762
|
|
||||||
|
|
||||||
Translations
|
Translations
|
||||||
- Gerhard Killesreiter 'killes' http://drupal.org/user/83
|
- Gerhard Killesreiter 'killes' http://drupal.org/user/83
|
||||||
|
|
||||||
@ -154,6 +145,20 @@ Node Access
|
|||||||
- Ken Rickard 'agentrickard' http://drupal.org/user/20975
|
- Ken Rickard 'agentrickard' http://drupal.org/user/20975
|
||||||
- Jess Myrbo 'xjm' http://drupal.org/user/65776
|
- Jess Myrbo 'xjm' http://drupal.org/user/65776
|
||||||
|
|
||||||
|
|
||||||
|
Security team
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
To report a security issue, see: https://drupal.org/security-team/report-issue
|
||||||
|
|
||||||
|
The Drupal security team provides Security Advisories for vulnerabilities,
|
||||||
|
assists developers in resolving security issues, and provides security
|
||||||
|
documentation. See http://drupal.org/security-team for more information. The
|
||||||
|
security team lead is:
|
||||||
|
|
||||||
|
- Michael Hess 'mlhess' https://drupal.org/user/102818
|
||||||
|
|
||||||
|
|
||||||
Module maintainers
|
Module maintainers
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
@ -250,7 +255,6 @@ Shortcut module
|
|||||||
|
|
||||||
Simpletest module
|
Simpletest module
|
||||||
- Jimmy Berry 'boombatower' http://drupal.org/user/214218
|
- Jimmy Berry 'boombatower' http://drupal.org/user/214218
|
||||||
- Károly Négyesi 'chx' http://drupal.org/user/9446
|
|
||||||
|
|
||||||
Statistics module
|
Statistics module
|
||||||
- Tim Millwood 'timmillwood' http://drupal.org/user/227849
|
- Tim Millwood 'timmillwood' http://drupal.org/user/227849
|
||||||
|
@ -211,7 +211,7 @@
|
|||||||
*
|
*
|
||||||
* When returning an Ajax command array, it is often useful to have
|
* When returning an Ajax command array, it is often useful to have
|
||||||
* status messages rendered along with other tasks in the command array.
|
* status messages rendered along with other tasks in the command array.
|
||||||
* In that case the the Ajax commands array may be constructed like this:
|
* In that case the Ajax commands array may be constructed like this:
|
||||||
* @code
|
* @code
|
||||||
* $commands = array();
|
* $commands = array();
|
||||||
* $commands[] = ajax_command_replace(NULL, $output);
|
* $commands[] = ajax_command_replace(NULL, $output);
|
||||||
@ -276,7 +276,7 @@ function ajax_render($commands = array()) {
|
|||||||
|
|
||||||
$extra_commands = array();
|
$extra_commands = array();
|
||||||
if (!empty($styles)) {
|
if (!empty($styles)) {
|
||||||
$extra_commands[] = ajax_command_prepend('head', $styles);
|
$extra_commands[] = ajax_command_add_css($styles);
|
||||||
}
|
}
|
||||||
if (!empty($scripts_header)) {
|
if (!empty($scripts_header)) {
|
||||||
$extra_commands[] = ajax_command_prepend('head', $scripts_header);
|
$extra_commands[] = ajax_command_prepend('head', $scripts_header);
|
||||||
@ -292,7 +292,7 @@ function ajax_render($commands = array()) {
|
|||||||
$scripts = drupal_add_js();
|
$scripts = drupal_add_js();
|
||||||
if (!empty($scripts['settings'])) {
|
if (!empty($scripts['settings'])) {
|
||||||
$settings = $scripts['settings'];
|
$settings = $scripts['settings'];
|
||||||
array_unshift($commands, ajax_command_settings(call_user_func_array('array_merge_recursive', $settings['data']), TRUE));
|
array_unshift($commands, ajax_command_settings(drupal_array_merge_deep_array($settings['data']), TRUE));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow modules to alter any Ajax response.
|
// Allow modules to alter any Ajax response.
|
||||||
@ -1257,3 +1257,26 @@ function ajax_command_update_build_id($form) {
|
|||||||
'new' => $form['#build_id'],
|
'new' => $form['#build_id'],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Drupal Ajax 'add_css' command.
|
||||||
|
*
|
||||||
|
* This method will add css via ajax in a cross-browser compatible way.
|
||||||
|
*
|
||||||
|
* This command is implemented by Drupal.ajax.prototype.commands.add_css()
|
||||||
|
* defined in misc/ajax.js.
|
||||||
|
*
|
||||||
|
* @param $styles
|
||||||
|
* A string that contains the styles to be added.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* An array suitable for use with the ajax_render() function.
|
||||||
|
*
|
||||||
|
* @see misc/ajax.js
|
||||||
|
*/
|
||||||
|
function ajax_command_add_css($styles) {
|
||||||
|
return array(
|
||||||
|
'command' => 'add_css',
|
||||||
|
'data' => $styles,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
/**
|
/**
|
||||||
* The current system version.
|
* The current system version.
|
||||||
*/
|
*/
|
||||||
define('VERSION', '7.28');
|
define('VERSION', '7.36');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Core API compatibility.
|
* Core API compatibility.
|
||||||
@ -248,6 +248,15 @@ define('REGISTRY_WRITE_LOOKUP_CACHE', 2);
|
|||||||
*/
|
*/
|
||||||
define('DRUPAL_PHP_FUNCTION_PATTERN', '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*');
|
define('DRUPAL_PHP_FUNCTION_PATTERN', '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A RFC7231 Compliant date.
|
||||||
|
*
|
||||||
|
* http://tools.ietf.org/html/rfc7231#section-7.1.1.1
|
||||||
|
*
|
||||||
|
* Example: Sun, 06 Nov 1994 08:49:37 GMT
|
||||||
|
*/
|
||||||
|
define('DATE_RFC7231', 'D, d M Y H:i:s \G\M\T');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a caching wrapper to be used in place of large array structures.
|
* Provides a caching wrapper to be used in place of large array structures.
|
||||||
*
|
*
|
||||||
@ -520,9 +529,8 @@ function timer_stop($name) {
|
|||||||
* Returns the appropriate configuration directory.
|
* Returns the appropriate configuration directory.
|
||||||
*
|
*
|
||||||
* Returns the configuration path based on the site's hostname, port, and
|
* Returns the configuration path based on the site's hostname, port, and
|
||||||
* pathname. Uses find_conf_path() to find the current configuration directory.
|
* pathname. See default.settings.php for examples on how the URL is converted
|
||||||
* See default.settings.php for examples on how the URL is converted to a
|
* to a directory.
|
||||||
* directory.
|
|
||||||
*
|
*
|
||||||
* @param bool $require_settings
|
* @param bool $require_settings
|
||||||
* Only configuration directories with an existing settings.php file
|
* Only configuration directories with an existing settings.php file
|
||||||
@ -700,7 +708,14 @@ function drupal_environment_initialize() {
|
|||||||
* TRUE if only containing valid characters, or FALSE otherwise.
|
* TRUE if only containing valid characters, or FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
function drupal_valid_http_host($host) {
|
function drupal_valid_http_host($host) {
|
||||||
return preg_match('/^\[?(?:[a-zA-Z0-9-:\]_]+\.?)+$/', $host);
|
// Limit the length of the host name to 1000 bytes to prevent DoS attacks with
|
||||||
|
// long host names.
|
||||||
|
return strlen($host) <= 1000
|
||||||
|
// Limit the number of subdomains and port separators to prevent DoS attacks
|
||||||
|
// in conf_path().
|
||||||
|
&& substr_count($host, '.') <= 100
|
||||||
|
&& substr_count($host, ':') <= 100
|
||||||
|
&& preg_match('/^\[?(?:[a-zA-Z0-9-:\]_]+\.?)+$/', $host);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -845,7 +860,7 @@ function drupal_get_filename($type, $name, $filename = NULL) {
|
|||||||
try {
|
try {
|
||||||
if (function_exists('db_query')) {
|
if (function_exists('db_query')) {
|
||||||
$file = db_query("SELECT filename FROM {system} WHERE name = :name AND type = :type", array(':name' => $name, ':type' => $type))->fetchField();
|
$file = db_query("SELECT filename FROM {system} WHERE name = :name AND type = :type", array(':name' => $name, ':type' => $type))->fetchField();
|
||||||
if (file_exists(DRUPAL_ROOT . '/' . $file)) {
|
if ($file !== FALSE && file_exists(DRUPAL_ROOT . '/' . $file)) {
|
||||||
$files[$type][$name] = $file;
|
$files[$type][$name] = $file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1230,23 +1245,10 @@ function drupal_send_headers($default_headers = array(), $only_default = FALSE)
|
|||||||
* fresh page on every request. This prevents authenticated users from seeing
|
* fresh page on every request. This prevents authenticated users from seeing
|
||||||
* locally cached pages.
|
* locally cached pages.
|
||||||
*
|
*
|
||||||
* Also give each page a unique ETag. This will force clients to include both
|
* ETag and Last-Modified headers are not set per default for authenticated
|
||||||
* an If-Modified-Since header and an If-None-Match header when doing
|
* users so that browsers do not send If-Modified-Since headers from
|
||||||
* conditional requests for the page (required by RFC 2616, section 13.3.4),
|
* authenticated user pages. drupal_serve_page_from_cache() will set appropriate
|
||||||
* making the validation more robust. This is a workaround for a bug in Mozilla
|
* ETag and Last-Modified headers for cached pages.
|
||||||
* Firefox that is triggered when Drupal's caching is enabled and the user
|
|
||||||
* accesses Drupal via an HTTP proxy (see
|
|
||||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=269303): When an authenticated
|
|
||||||
* user requests a page, and then logs out and requests the same page again,
|
|
||||||
* Firefox may send a conditional request based on the page that was cached
|
|
||||||
* locally when the user was logged in. If this page did not have an ETag
|
|
||||||
* header, the request only contains an If-Modified-Since header. The date will
|
|
||||||
* be recent, because with authenticated users the Last-Modified header always
|
|
||||||
* refers to the time of the request. If the user accesses Drupal via a proxy
|
|
||||||
* server, and the proxy already has a cached copy of the anonymous page with an
|
|
||||||
* older Last-Modified date, the proxy may respond with 304 Not Modified, making
|
|
||||||
* the client think that the anonymous and authenticated pageviews are
|
|
||||||
* identical.
|
|
||||||
*
|
*
|
||||||
* @see drupal_page_set_cache()
|
* @see drupal_page_set_cache()
|
||||||
*/
|
*/
|
||||||
@ -1259,9 +1261,7 @@ function drupal_page_header() {
|
|||||||
|
|
||||||
$default_headers = array(
|
$default_headers = array(
|
||||||
'Expires' => 'Sun, 19 Nov 1978 05:00:00 GMT',
|
'Expires' => 'Sun, 19 Nov 1978 05:00:00 GMT',
|
||||||
'Last-Modified' => gmdate(DATE_RFC1123, REQUEST_TIME),
|
|
||||||
'Cache-Control' => 'no-cache, must-revalidate, post-check=0, pre-check=0',
|
'Cache-Control' => 'no-cache, must-revalidate, post-check=0, pre-check=0',
|
||||||
'ETag' => '"' . REQUEST_TIME . '"',
|
|
||||||
);
|
);
|
||||||
drupal_send_headers($default_headers);
|
drupal_send_headers($default_headers);
|
||||||
}
|
}
|
||||||
@ -1329,7 +1329,7 @@ function drupal_serve_page_from_cache(stdClass $cache) {
|
|||||||
drupal_add_http_header($name, $value);
|
drupal_add_http_header($name, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
$default_headers['Last-Modified'] = gmdate(DATE_RFC1123, $cache->created);
|
$default_headers['Last-Modified'] = gmdate(DATE_RFC7231, $cache->created);
|
||||||
|
|
||||||
// HTTP/1.0 proxies does not support the Vary header, so prevent any caching
|
// HTTP/1.0 proxies does not support the Vary header, so prevent any caching
|
||||||
// by sending an Expires date in the past. HTTP/1.1 clients ignores the
|
// by sending an Expires date in the past. HTTP/1.1 clients ignores the
|
||||||
@ -1552,12 +1552,13 @@ function format_string($string, array $args = array()) {
|
|||||||
* Also validates strings as UTF-8 to prevent cross site scripting attacks on
|
* Also validates strings as UTF-8 to prevent cross site scripting attacks on
|
||||||
* Internet Explorer 6.
|
* Internet Explorer 6.
|
||||||
*
|
*
|
||||||
* @param $text
|
* @param string $text
|
||||||
* The text to be checked or processed.
|
* The text to be checked or processed.
|
||||||
*
|
*
|
||||||
* @return
|
* @return string
|
||||||
* An HTML safe version of $text, or an empty string if $text is not
|
* An HTML safe version of $text. If $text is not valid UTF-8, an empty string
|
||||||
* valid UTF-8.
|
* is returned and, on PHP < 5.4, a warning may be issued depending on server
|
||||||
|
* configuration (see @link https://bugs.php.net/bug.php?id=47494 @endlink).
|
||||||
*
|
*
|
||||||
* @see drupal_validate_utf8()
|
* @see drupal_validate_utf8()
|
||||||
* @ingroup sanitization
|
* @ingroup sanitization
|
||||||
@ -1642,14 +1643,14 @@ function request_uri() {
|
|||||||
* information about the passed-in exception is used.
|
* information about the passed-in exception is used.
|
||||||
* @param $variables
|
* @param $variables
|
||||||
* Array of variables to replace in the message on display. Defaults to the
|
* Array of variables to replace in the message on display. Defaults to the
|
||||||
* return value of drupal_decode_exception().
|
* return value of _drupal_decode_exception().
|
||||||
* @param $severity
|
* @param $severity
|
||||||
* The severity of the message, as per RFC 3164.
|
* The severity of the message, as per RFC 3164.
|
||||||
* @param $link
|
* @param $link
|
||||||
* A link to associate with the message.
|
* A link to associate with the message.
|
||||||
*
|
*
|
||||||
* @see watchdog()
|
* @see watchdog()
|
||||||
* @see drupal_decode_exception()
|
* @see _drupal_decode_exception()
|
||||||
*/
|
*/
|
||||||
function watchdog_exception($type, Exception $exception, $message = NULL, $variables = array(), $severity = WATCHDOG_ERROR, $link = NULL) {
|
function watchdog_exception($type, Exception $exception, $message = NULL, $variables = array(), $severity = WATCHDOG_ERROR, $link = NULL) {
|
||||||
|
|
||||||
@ -2169,7 +2170,7 @@ function drupal_anonymous_user() {
|
|||||||
* drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
|
* drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
|
||||||
* @endcode
|
* @endcode
|
||||||
*
|
*
|
||||||
* @param $phase
|
* @param int $phase
|
||||||
* A constant telling which phase to bootstrap to. When you bootstrap to a
|
* A constant telling which phase to bootstrap to. When you bootstrap to a
|
||||||
* particular phase, all earlier phases are run automatically. Possible
|
* particular phase, all earlier phases are run automatically. Possible
|
||||||
* values:
|
* values:
|
||||||
@ -2182,11 +2183,11 @@ function drupal_anonymous_user() {
|
|||||||
* - DRUPAL_BOOTSTRAP_LANGUAGE: Finds out the language of the page.
|
* - DRUPAL_BOOTSTRAP_LANGUAGE: Finds out the language of the page.
|
||||||
* - DRUPAL_BOOTSTRAP_FULL: Fully loads Drupal. Validates and fixes input
|
* - DRUPAL_BOOTSTRAP_FULL: Fully loads Drupal. Validates and fixes input
|
||||||
* data.
|
* data.
|
||||||
* @param $new_phase
|
* @param boolean $new_phase
|
||||||
* A boolean, set to FALSE if calling drupal_bootstrap from inside a
|
* A boolean, set to FALSE if calling drupal_bootstrap from inside a
|
||||||
* function called from drupal_bootstrap (recursion).
|
* function called from drupal_bootstrap (recursion).
|
||||||
*
|
*
|
||||||
* @return
|
* @return int
|
||||||
* The most recently completed phase.
|
* The most recently completed phase.
|
||||||
*/
|
*/
|
||||||
function drupal_bootstrap($phase = NULL, $new_phase = TRUE) {
|
function drupal_bootstrap($phase = NULL, $new_phase = TRUE) {
|
||||||
@ -2208,12 +2209,13 @@ function drupal_bootstrap($phase = NULL, $new_phase = TRUE) {
|
|||||||
// bootstrap state.
|
// bootstrap state.
|
||||||
static $stored_phase = -1;
|
static $stored_phase = -1;
|
||||||
|
|
||||||
// When not recursing, store the phase name so it's not forgotten while
|
|
||||||
// recursing.
|
|
||||||
if ($new_phase) {
|
|
||||||
$final_phase = $phase;
|
|
||||||
}
|
|
||||||
if (isset($phase)) {
|
if (isset($phase)) {
|
||||||
|
// When not recursing, store the phase name so it's not forgotten while
|
||||||
|
// recursing but take care of not going backwards.
|
||||||
|
if ($new_phase && $phase >= $stored_phase) {
|
||||||
|
$final_phase = $phase;
|
||||||
|
}
|
||||||
|
|
||||||
// Call a phase if it has not been called before and is below the requested
|
// Call a phase if it has not been called before and is below the requested
|
||||||
// phase.
|
// phase.
|
||||||
while ($phases && $phase > $stored_phase && $final_phase > $stored_phase) {
|
while ($phases && $phase > $stored_phase && $final_phase > $stored_phase) {
|
||||||
@ -2479,6 +2481,26 @@ function _drupal_bootstrap_variables() {
|
|||||||
// Load bootstrap modules.
|
// Load bootstrap modules.
|
||||||
require_once DRUPAL_ROOT . '/includes/module.inc';
|
require_once DRUPAL_ROOT . '/includes/module.inc';
|
||||||
module_load_all(TRUE);
|
module_load_all(TRUE);
|
||||||
|
|
||||||
|
// Sanitize the destination parameter (which is often used for redirects) to
|
||||||
|
// prevent open redirect attacks leading to other domains. Sanitize both
|
||||||
|
// $_GET['destination'] and $_REQUEST['destination'] to protect code that
|
||||||
|
// relies on either, but do not sanitize $_POST to avoid interfering with
|
||||||
|
// unrelated form submissions. The sanitization happens here because
|
||||||
|
// url_is_external() requires the variable system to be available.
|
||||||
|
if (isset($_GET['destination']) || isset($_REQUEST['destination'])) {
|
||||||
|
require_once DRUPAL_ROOT . '/includes/common.inc';
|
||||||
|
// If the destination is an external URL, remove it.
|
||||||
|
if (isset($_GET['destination']) && url_is_external($_GET['destination'])) {
|
||||||
|
unset($_GET['destination']);
|
||||||
|
unset($_REQUEST['destination']);
|
||||||
|
}
|
||||||
|
// If there's still something in $_REQUEST['destination'] that didn't come
|
||||||
|
// from $_GET, check it too.
|
||||||
|
if (isset($_REQUEST['destination']) && (!isset($_GET['destination']) || $_REQUEST['destination'] != $_GET['destination']) && url_is_external($_REQUEST['destination'])) {
|
||||||
|
unset($_REQUEST['destination']);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2501,7 +2523,7 @@ function _drupal_bootstrap_page_header() {
|
|||||||
* @see drupal_bootstrap()
|
* @see drupal_bootstrap()
|
||||||
*/
|
*/
|
||||||
function drupal_get_bootstrap_phase() {
|
function drupal_get_bootstrap_phase() {
|
||||||
return drupal_bootstrap();
|
return drupal_bootstrap(NULL, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2615,7 +2637,7 @@ function drupal_installation_attempted() {
|
|||||||
*
|
*
|
||||||
* This would include implementations of hook_install(), which could run
|
* This would include implementations of hook_install(), which could run
|
||||||
* during the Drupal installation phase, and might also be run during
|
* during the Drupal installation phase, and might also be run during
|
||||||
* non-installation time, such as while installing the module from the the
|
* non-installation time, such as while installing the module from the
|
||||||
* module administration page.
|
* module administration page.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
@ -3144,10 +3166,13 @@ function _registry_check_code($type, $name = NULL) {
|
|||||||
// This function may get called when the default database is not active, but
|
// This function may get called when the default database is not active, but
|
||||||
// there is no reason we'd ever want to not use the default database for
|
// there is no reason we'd ever want to not use the default database for
|
||||||
// this query.
|
// this query.
|
||||||
$file = Database::getConnection('default', 'default')->query("SELECT filename FROM {registry} WHERE name = :name AND type = :type", array(
|
$file = Database::getConnection('default', 'default')
|
||||||
':name' => $name,
|
->select('registry', 'r', array('target' => 'default'))
|
||||||
':type' => $type,
|
->fields('r', array('filename'))
|
||||||
))
|
// Use LIKE here to make the query case-insensitive.
|
||||||
|
->condition('r.name', db_like($name), 'LIKE')
|
||||||
|
->condition('r.type', $type)
|
||||||
|
->execute()
|
||||||
->fetchField();
|
->fetchField();
|
||||||
|
|
||||||
// Flag that we've run a lookup query and need to update the cache.
|
// Flag that we've run a lookup query and need to update the cache.
|
||||||
@ -3321,11 +3346,9 @@ function registry_update() {
|
|||||||
* @param $default_value
|
* @param $default_value
|
||||||
* Optional default value.
|
* Optional default value.
|
||||||
* @param $reset
|
* @param $reset
|
||||||
* TRUE to reset a specific named variable, or all variables if $name is NULL.
|
* TRUE to reset one or all variables(s). This parameter is only used
|
||||||
* Resetting every variable should only be used, for example, for running
|
* internally and should not be passed in; use drupal_static_reset() instead.
|
||||||
* unit tests with a clean environment. Should be used only though via
|
* (This function's return value should not be used when TRUE is passed in.)
|
||||||
* function drupal_static_reset() and the return value should not be used in
|
|
||||||
* this case.
|
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* Returns a variable by reference.
|
* Returns a variable by reference.
|
||||||
@ -3370,6 +3393,8 @@ function &drupal_static($name, $default_value = NULL, $reset = FALSE) {
|
|||||||
*
|
*
|
||||||
* @param $name
|
* @param $name
|
||||||
* Name of the static variable to reset. Omit to reset all variables.
|
* Name of the static variable to reset. Omit to reset all variables.
|
||||||
|
* Resetting all variables should only be used, for example, for running unit
|
||||||
|
* tests with a clean environment.
|
||||||
*/
|
*/
|
||||||
function drupal_static_reset($name = NULL) {
|
function drupal_static_reset($name = NULL) {
|
||||||
drupal_static($name, NULL, TRUE);
|
drupal_static($name, NULL, TRUE);
|
||||||
@ -3485,3 +3510,34 @@ function drupal_check_memory_limit($required, $memory_limit = NULL) {
|
|||||||
// - The memory limit is greater than the memory required for the operation.
|
// - 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)));
|
return ((!$memory_limit) || ($memory_limit == -1) || (parse_size($memory_limit) >= parse_size($required)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates a PHP file from any active opcode caches.
|
||||||
|
*
|
||||||
|
* If the opcode cache does not support the invalidation of individual files,
|
||||||
|
* the entire cache will be flushed.
|
||||||
|
*
|
||||||
|
* @param string $filepath
|
||||||
|
* The absolute path of the PHP file to invalidate.
|
||||||
|
*/
|
||||||
|
function drupal_clear_opcode_cache($filepath) {
|
||||||
|
if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50300) {
|
||||||
|
// Below PHP 5.3, clearstatcache does not accept any function parameters.
|
||||||
|
clearstatcache();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clearstatcache(TRUE, $filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zend OPcache.
|
||||||
|
if (function_exists('opcache_invalidate')) {
|
||||||
|
opcache_invalidate($filepath, TRUE);
|
||||||
|
}
|
||||||
|
// APC.
|
||||||
|
if (function_exists('apc_delete_file')) {
|
||||||
|
// apc_delete_file() throws a PHP warning in case the specified file was
|
||||||
|
// not compiled yet.
|
||||||
|
// @see http://php.net/apc-delete-file
|
||||||
|
@apc_delete_file($filepath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -98,9 +98,11 @@ function cache_get_multiple(array &$cids, $bin = 'cache') {
|
|||||||
* @param $data
|
* @param $data
|
||||||
* The data to store in the cache. Complex data types will be automatically
|
* The data to store in the cache. Complex data types will be automatically
|
||||||
* serialized before insertion. Strings will be stored as plain text and are
|
* serialized before insertion. Strings will be stored as plain text and are
|
||||||
* not serialized.
|
* not serialized. Some storage engines only allow objects up to a maximum of
|
||||||
|
* 1MB in size to be stored by default. When caching large arrays or similar,
|
||||||
|
* take care to ensure $data does not exceed this size.
|
||||||
* @param $bin
|
* @param $bin
|
||||||
* The cache bin to store the data in. Valid core values are:
|
* (optional) The cache bin to store the data in. Valid core values are:
|
||||||
* - cache: (default) Generic cache storage bin (used for theme registry,
|
* - cache: (default) Generic cache storage bin (used for theme registry,
|
||||||
* locale date, list of simpletest tests, etc.).
|
* locale date, list of simpletest tests, etc.).
|
||||||
* - cache_block: Stores the content of various blocks.
|
* - cache_block: Stores the content of various blocks.
|
||||||
@ -119,7 +121,7 @@ function cache_get_multiple(array &$cids, $bin = 'cache') {
|
|||||||
* the administrator panel.
|
* the administrator panel.
|
||||||
* - cache_path: Stores the system paths that have an alias.
|
* - cache_path: Stores the system paths that have an alias.
|
||||||
* @param $expire
|
* @param $expire
|
||||||
* One of the following values:
|
* (optional) One of the following values:
|
||||||
* - CACHE_PERMANENT: Indicates that the item should never be removed unless
|
* - CACHE_PERMANENT: Indicates that the item should never be removed unless
|
||||||
* explicitly told to using cache_clear_all() with a cache ID.
|
* explicitly told to using cache_clear_all() with a cache ID.
|
||||||
* - CACHE_TEMPORARY: Indicates that the item should be removed at the next
|
* - CACHE_TEMPORARY: Indicates that the item should be removed at the next
|
||||||
@ -254,10 +256,12 @@ interface DrupalCacheInterface {
|
|||||||
* The cache ID of the data to store.
|
* The cache ID of the data to store.
|
||||||
* @param $data
|
* @param $data
|
||||||
* The data to store in the cache. Complex data types will be automatically
|
* The data to store in the cache. Complex data types will be automatically
|
||||||
* serialized before insertion.
|
* serialized before insertion. Strings will be stored as plain text and not
|
||||||
* Strings will be stored as plain text and not serialized.
|
* serialized. Some storage engines only allow objects up to a maximum of
|
||||||
|
* 1MB in size to be stored by default. When caching large arrays or
|
||||||
|
* similar, take care to ensure $data does not exceed this size.
|
||||||
* @param $expire
|
* @param $expire
|
||||||
* One of the following values:
|
* (optional) One of the following values:
|
||||||
* - CACHE_PERMANENT: Indicates that the item should never be removed unless
|
* - CACHE_PERMANENT: Indicates that the item should never be removed unless
|
||||||
* explicitly told to using cache_clear_all() with a cache ID.
|
* explicitly told to using cache_clear_all() with a cache ID.
|
||||||
* - CACHE_TEMPORARY: Indicates that the item should be removed at the next
|
* - CACHE_TEMPORARY: Indicates that the item should be removed at the next
|
||||||
|
@ -544,37 +544,32 @@ function drupal_get_destination() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a system URL string into an associative array suitable for url().
|
* Parses a URL string into its path, query, and fragment components.
|
||||||
*
|
*
|
||||||
* This function should only be used for URLs that have been generated by the
|
* This function splits both internal paths like @code node?b=c#d @endcode and
|
||||||
* system, such as via url(). It should not be used for URLs that come from
|
* external URLs like @code https://example.com/a?b=c#d @endcode into their
|
||||||
* external sources, or URLs that link to external resources.
|
* component parts. See
|
||||||
|
* @link http://tools.ietf.org/html/rfc3986#section-3 RFC 3986 @endlink for an
|
||||||
|
* explanation of what the component parts are.
|
||||||
*
|
*
|
||||||
* The returned array contains a 'path' that may be passed separately to url().
|
* Note that, unlike the RFC, when passed an external URL, this function
|
||||||
* For example:
|
* groups the scheme, authority, and path together into the path component.
|
||||||
* @code
|
|
||||||
* $options = drupal_parse_url($_GET['destination']);
|
|
||||||
* $my_url = url($options['path'], $options);
|
|
||||||
* $my_link = l('Example link', $options['path'], $options);
|
|
||||||
* @endcode
|
|
||||||
*
|
*
|
||||||
* This is required, because url() does not support relative URLs containing a
|
* @param string $url
|
||||||
* query string or fragment in its $path argument. Instead, any query string
|
* The internal path or external URL string to parse.
|
||||||
* needs to be parsed into an associative query parameter array in
|
|
||||||
* $options['query'] and the fragment into $options['fragment'].
|
|
||||||
*
|
*
|
||||||
* @param $url
|
* @return array
|
||||||
* The URL string to parse, f.e. $_GET['destination'].
|
* An associative array containing:
|
||||||
|
* - path: The path component of $url. If $url is an external URL, this
|
||||||
|
* includes the scheme, authority, and path.
|
||||||
|
* - query: An array of query parameters from $url, if they exist.
|
||||||
|
* - fragment: The fragment component from $url, if it exists.
|
||||||
*
|
*
|
||||||
* @return
|
|
||||||
* An associative array containing the keys:
|
|
||||||
* - 'path': The path of the URL. If the given $url is external, this includes
|
|
||||||
* the scheme and host.
|
|
||||||
* - 'query': An array of query parameters of $url, if existent.
|
|
||||||
* - 'fragment': The fragment of $url, if existent.
|
|
||||||
*
|
|
||||||
* @see url()
|
|
||||||
* @see drupal_goto()
|
* @see drupal_goto()
|
||||||
|
* @see l()
|
||||||
|
* @see url()
|
||||||
|
* @see http://tools.ietf.org/html/rfc3986
|
||||||
|
*
|
||||||
* @ingroup php_wrappers
|
* @ingroup php_wrappers
|
||||||
*/
|
*/
|
||||||
function drupal_parse_url($url) {
|
function drupal_parse_url($url) {
|
||||||
@ -990,9 +985,10 @@ function drupal_http_request($url, array $options = array()) {
|
|||||||
$response = preg_split("/\r\n|\n|\r/", $response);
|
$response = preg_split("/\r\n|\n|\r/", $response);
|
||||||
|
|
||||||
// Parse the response status line.
|
// Parse the response status line.
|
||||||
list($protocol, $code, $status_message) = explode(' ', trim(array_shift($response)), 3);
|
$response_status_array = _drupal_parse_response_status(trim(array_shift($response)));
|
||||||
$result->protocol = $protocol;
|
$result->protocol = $response_status_array['http_version'];
|
||||||
$result->status_message = $status_message;
|
$result->status_message = $response_status_array['reason_phrase'];
|
||||||
|
$code = $response_status_array['response_code'];
|
||||||
|
|
||||||
$result->headers = array();
|
$result->headers = array();
|
||||||
|
|
||||||
@ -1083,12 +1079,43 @@ function drupal_http_request($url, array $options = array()) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$result->error = $status_message;
|
$result->error = $result->status_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Splits an HTTP response status line into components.
|
||||||
|
*
|
||||||
|
* See the @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html status line definition @endlink
|
||||||
|
* in RFC 2616.
|
||||||
|
*
|
||||||
|
* @param string $respone
|
||||||
|
* The response status line, for example 'HTTP/1.1 500 Internal Server Error'.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* Keyed array containing the component parts. If the response is malformed,
|
||||||
|
* all possible parts will be extracted. 'reason_phrase' could be empty.
|
||||||
|
* Possible keys:
|
||||||
|
* - 'http_version'
|
||||||
|
* - 'response_code'
|
||||||
|
* - 'reason_phrase'
|
||||||
|
*/
|
||||||
|
function _drupal_parse_response_status($response) {
|
||||||
|
$response_array = explode(' ', trim($response), 3);
|
||||||
|
// Set up empty values.
|
||||||
|
$result = array(
|
||||||
|
'reason_phrase' => '',
|
||||||
|
);
|
||||||
|
$result['http_version'] = $response_array[0];
|
||||||
|
$result['response_code'] = $response_array[1];
|
||||||
|
if (isset($response_array[2])) {
|
||||||
|
$result['reason_phrase'] = $response_array[2];
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function for determining hosts excluded from needing a proxy.
|
* Helper function for determining hosts excluded from needing a proxy.
|
||||||
*
|
*
|
||||||
@ -2187,14 +2214,20 @@ function url($path = NULL, array $options = array()) {
|
|||||||
'prefix' => ''
|
'prefix' => ''
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// A duplicate of the code from url_is_external() to avoid needing another
|
||||||
|
// function call, since performance inside url() is critical.
|
||||||
if (!isset($options['external'])) {
|
if (!isset($options['external'])) {
|
||||||
// Return an external link if $path contains an allowed absolute URL. Only
|
// Return an external link if $path contains an allowed absolute URL. Avoid
|
||||||
// call the slow drupal_strip_dangerous_protocols() if $path contains a ':'
|
// calling drupal_strip_dangerous_protocols() if there is any slash (/),
|
||||||
// before any / ? or #. Note: we could use url_is_external($path) here, but
|
// hash (#) or question_mark (?) before the colon (:) occurrence - if any -
|
||||||
// that would require another function call, and performance inside url() is
|
// as this would clearly mean it is not a URL. If the path starts with 2
|
||||||
// critical.
|
// slashes then it is always considered an external URL without an explicit
|
||||||
|
// protocol part.
|
||||||
$colonpos = strpos($path, ':');
|
$colonpos = strpos($path, ':');
|
||||||
$options['external'] = ($colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && drupal_strip_dangerous_protocols($path) == $path);
|
$options['external'] = (strpos($path, '//') === 0)
|
||||||
|
|| ($colonpos !== FALSE
|
||||||
|
&& !preg_match('![/?#]!', substr($path, 0, $colonpos))
|
||||||
|
&& drupal_strip_dangerous_protocols($path) == $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preserve the original path before altering or aliasing.
|
// Preserve the original path before altering or aliasing.
|
||||||
@ -2232,6 +2265,11 @@ function url($path = NULL, array $options = array()) {
|
|||||||
return $path . $options['fragment'];
|
return $path . $options['fragment'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Strip leading slashes from internal paths to prevent them becoming external
|
||||||
|
// URLs without protocol. /example.com should not be turned into
|
||||||
|
// //example.com.
|
||||||
|
$path = ltrim($path, '/');
|
||||||
|
|
||||||
global $base_url, $base_secure_url, $base_insecure_url;
|
global $base_url, $base_secure_url, $base_insecure_url;
|
||||||
|
|
||||||
// The base_url might be rewritten from the language rewrite in domain mode.
|
// The base_url might be rewritten from the language rewrite in domain mode.
|
||||||
@ -2309,10 +2347,15 @@ function url($path = NULL, array $options = array()) {
|
|||||||
*/
|
*/
|
||||||
function url_is_external($path) {
|
function url_is_external($path) {
|
||||||
$colonpos = strpos($path, ':');
|
$colonpos = strpos($path, ':');
|
||||||
// Avoid calling drupal_strip_dangerous_protocols() if there is any
|
// Avoid calling drupal_strip_dangerous_protocols() if there is any slash (/),
|
||||||
// slash (/), hash (#) or question_mark (?) before the colon (:)
|
// hash (#) or question_mark (?) before the colon (:) occurrence - if any - as
|
||||||
// occurrence - if any - as this would clearly mean it is not a URL.
|
// this would clearly mean it is not a URL. If the path starts with 2 slashes
|
||||||
return $colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && drupal_strip_dangerous_protocols($path) == $path;
|
// then it is always considered an external URL without an explicit protocol
|
||||||
|
// part.
|
||||||
|
return (strpos($path, '//') === 0)
|
||||||
|
|| ($colonpos !== FALSE
|
||||||
|
&& !preg_match('![/?#]!', substr($path, 0, $colonpos))
|
||||||
|
&& drupal_strip_dangerous_protocols($path) == $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2609,7 +2652,10 @@ function drupal_deliver_html_page($page_callback_result) {
|
|||||||
|
|
||||||
// Keep old path for reference, and to allow forms to redirect to it.
|
// Keep old path for reference, and to allow forms to redirect to it.
|
||||||
if (!isset($_GET['destination'])) {
|
if (!isset($_GET['destination'])) {
|
||||||
$_GET['destination'] = $_GET['q'];
|
// Make sure that the current path is not interpreted as external URL.
|
||||||
|
if (!url_is_external($_GET['q'])) {
|
||||||
|
$_GET['destination'] = $_GET['q'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$path = drupal_get_normal_path(variable_get('site_404', ''));
|
$path = drupal_get_normal_path(variable_get('site_404', ''));
|
||||||
@ -2638,7 +2684,10 @@ function drupal_deliver_html_page($page_callback_result) {
|
|||||||
|
|
||||||
// Keep old path for reference, and to allow forms to redirect to it.
|
// Keep old path for reference, and to allow forms to redirect to it.
|
||||||
if (!isset($_GET['destination'])) {
|
if (!isset($_GET['destination'])) {
|
||||||
$_GET['destination'] = $_GET['q'];
|
// Make sure that the current path is not interpreted as external URL.
|
||||||
|
if (!url_is_external($_GET['q'])) {
|
||||||
|
$_GET['destination'] = $_GET['q'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$path = drupal_get_normal_path(variable_get('site_403', ''));
|
$path = drupal_get_normal_path(variable_get('site_403', ''));
|
||||||
@ -3447,7 +3496,11 @@ function drupal_pre_render_styles($elements) {
|
|||||||
$import_batch = array_slice($import, 0, 31);
|
$import_batch = array_slice($import, 0, 31);
|
||||||
$import = array_slice($import, 31);
|
$import = array_slice($import, 31);
|
||||||
$element = $style_element_defaults;
|
$element = $style_element_defaults;
|
||||||
$element['#value'] = implode("\n", $import_batch);
|
// This simplifies the JavaScript regex, allowing each line
|
||||||
|
// (separated by \n) to be treated as a completely different string.
|
||||||
|
// This means that we can use ^ and $ on one line at a time, and not
|
||||||
|
// worry about style tags since they'll never match the regex.
|
||||||
|
$element['#value'] = "\n" . implode("\n", $import_batch) . "\n";
|
||||||
$element['#attributes']['media'] = $group['media'];
|
$element['#attributes']['media'] = $group['media'];
|
||||||
$element['#browsers'] = $group['browsers'];
|
$element['#browsers'] = $group['browsers'];
|
||||||
$elements[] = $element;
|
$elements[] = $element;
|
||||||
@ -3773,7 +3826,7 @@ function _drupal_load_stylesheet($matches) {
|
|||||||
// Alter all internal url() paths. Leave external paths alone. We don't need
|
// Alter all internal url() paths. Leave external paths alone. We don't need
|
||||||
// to normalize absolute paths here (i.e. remove folder/... segments) because
|
// to normalize absolute paths here (i.e. remove folder/... segments) because
|
||||||
// that will be done later.
|
// that will be done later.
|
||||||
return preg_replace('/url\(\s*([\'"]?)(?![a-z]+:|\/+)/i', 'url(\1'. $directory, $file);
|
return preg_replace('/url\(\s*([\'"]?)(?![a-z]+:|\/+)([^\'")]+)([\'"]?)\s*\)/i', 'url(\1' . $directory . '\2\3)', $file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4109,6 +4162,13 @@ function drupal_region_class($region) {
|
|||||||
* else being the same, JavaScript added by a call to drupal_add_js() that
|
* else being the same, JavaScript added by a call to drupal_add_js() that
|
||||||
* happened later in the page request gets added to the page after one for
|
* happened later in the page request gets added to the page after one for
|
||||||
* which drupal_add_js() happened earlier in the page request.
|
* which drupal_add_js() happened earlier in the page request.
|
||||||
|
* - requires_jquery: Set this to FALSE if the JavaScript you are adding does
|
||||||
|
* not have a dependency on jQuery. Defaults to TRUE, except for JavaScript
|
||||||
|
* settings where it defaults to FALSE. This is used on sites that have the
|
||||||
|
* 'javascript_always_use_jquery' variable set to FALSE; on those sites, if
|
||||||
|
* all the JavaScript added to the page by drupal_add_js() does not have a
|
||||||
|
* dependency on jQuery, then for improved front-end performance Drupal
|
||||||
|
* will not add jQuery and related libraries and settings to the page.
|
||||||
* - defer: If set to TRUE, the defer attribute is set on the <script>
|
* - defer: If set to TRUE, the defer attribute is set on the <script>
|
||||||
* tag. Defaults to FALSE.
|
* tag. Defaults to FALSE.
|
||||||
* - cache: If set to FALSE, the JavaScript file is loaded anew on every page
|
* - cache: If set to FALSE, the JavaScript file is loaded anew on every page
|
||||||
@ -4126,6 +4186,14 @@ function drupal_region_class($region) {
|
|||||||
*/
|
*/
|
||||||
function drupal_add_js($data = NULL, $options = NULL) {
|
function drupal_add_js($data = NULL, $options = NULL) {
|
||||||
$javascript = &drupal_static(__FUNCTION__, array());
|
$javascript = &drupal_static(__FUNCTION__, array());
|
||||||
|
$jquery_added = &drupal_static(__FUNCTION__ . ':jquery_added', FALSE);
|
||||||
|
|
||||||
|
// If the $javascript variable has been reset with drupal_static_reset(),
|
||||||
|
// jQuery and related files will have been removed from the list, so set the
|
||||||
|
// variable back to FALSE to indicate they have not yet been added.
|
||||||
|
if (empty($javascript)) {
|
||||||
|
$jquery_added = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
// Construct the options, taking the defaults into consideration.
|
// Construct the options, taking the defaults into consideration.
|
||||||
if (isset($options)) {
|
if (isset($options)) {
|
||||||
@ -4136,6 +4204,9 @@ function drupal_add_js($data = NULL, $options = NULL) {
|
|||||||
else {
|
else {
|
||||||
$options = array();
|
$options = array();
|
||||||
}
|
}
|
||||||
|
if (isset($options['type']) && $options['type'] == 'setting') {
|
||||||
|
$options += array('requires_jquery' => FALSE);
|
||||||
|
}
|
||||||
$options += drupal_js_defaults($data);
|
$options += drupal_js_defaults($data);
|
||||||
|
|
||||||
// Preprocess can only be set if caching is enabled.
|
// Preprocess can only be set if caching is enabled.
|
||||||
@ -4146,14 +4217,18 @@ function drupal_add_js($data = NULL, $options = NULL) {
|
|||||||
$options['weight'] += count($javascript) / 1000;
|
$options['weight'] += count($javascript) / 1000;
|
||||||
|
|
||||||
if (isset($data)) {
|
if (isset($data)) {
|
||||||
// Add jquery.js and drupal.js, as well as the basePath setting, the
|
// Add jquery.js, drupal.js, and related files and settings if they have
|
||||||
// first time a JavaScript file is added.
|
// not been added yet. However, if the 'javascript_always_use_jquery'
|
||||||
if (empty($javascript)) {
|
// variable is set to FALSE (indicating that the site does not want jQuery
|
||||||
|
// automatically added on all pages) then only add it if a file or setting
|
||||||
|
// that requires jQuery is being added also.
|
||||||
|
if (!$jquery_added && (variable_get('javascript_always_use_jquery', TRUE) || $options['requires_jquery'])) {
|
||||||
|
$jquery_added = TRUE;
|
||||||
// url() generates the prefix using hook_url_outbound_alter(). Instead of
|
// url() generates the prefix using hook_url_outbound_alter(). Instead of
|
||||||
// running the hook_url_outbound_alter() again here, extract the prefix
|
// running the hook_url_outbound_alter() again here, extract the prefix
|
||||||
// from url().
|
// from url().
|
||||||
url('', array('prefix' => &$prefix));
|
url('', array('prefix' => &$prefix));
|
||||||
$javascript = array(
|
$default_javascript = array(
|
||||||
'settings' => array(
|
'settings' => array(
|
||||||
'data' => array(
|
'data' => array(
|
||||||
array('basePath' => base_path()),
|
array('basePath' => base_path()),
|
||||||
@ -4172,11 +4247,13 @@ function drupal_add_js($data = NULL, $options = NULL) {
|
|||||||
'group' => JS_LIBRARY,
|
'group' => JS_LIBRARY,
|
||||||
'every_page' => TRUE,
|
'every_page' => TRUE,
|
||||||
'weight' => -1,
|
'weight' => -1,
|
||||||
|
'requires_jquery' => TRUE,
|
||||||
'preprocess' => TRUE,
|
'preprocess' => TRUE,
|
||||||
'cache' => TRUE,
|
'cache' => TRUE,
|
||||||
'defer' => FALSE,
|
'defer' => FALSE,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
$javascript = drupal_array_merge_deep($javascript, $default_javascript);
|
||||||
// Register all required libraries.
|
// Register all required libraries.
|
||||||
drupal_add_library('system', 'jquery', TRUE);
|
drupal_add_library('system', 'jquery', TRUE);
|
||||||
drupal_add_library('system', 'jquery.once', TRUE);
|
drupal_add_library('system', 'jquery.once', TRUE);
|
||||||
@ -4217,6 +4294,7 @@ function drupal_js_defaults($data = NULL) {
|
|||||||
'group' => JS_DEFAULT,
|
'group' => JS_DEFAULT,
|
||||||
'every_page' => FALSE,
|
'every_page' => FALSE,
|
||||||
'weight' => 0,
|
'weight' => 0,
|
||||||
|
'requires_jquery' => TRUE,
|
||||||
'scope' => 'header',
|
'scope' => 'header',
|
||||||
'cache' => TRUE,
|
'cache' => TRUE,
|
||||||
'defer' => FALSE,
|
'defer' => FALSE,
|
||||||
@ -4263,7 +4341,12 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
|
|||||||
if (!isset($javascript)) {
|
if (!isset($javascript)) {
|
||||||
$javascript = drupal_add_js();
|
$javascript = drupal_add_js();
|
||||||
}
|
}
|
||||||
if (empty($javascript)) {
|
|
||||||
|
// If no JavaScript items have been added, or if the only JavaScript items
|
||||||
|
// that have been added are JavaScript settings (which don't do anything
|
||||||
|
// without any JavaScript code to use them), then no JavaScript code should
|
||||||
|
// be added to the page.
|
||||||
|
if (empty($javascript) || (isset($javascript['settings']) && count($javascript) == 1)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4417,8 +4500,8 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
|
|||||||
*
|
*
|
||||||
* Libraries, JavaScript, CSS and other types of custom structures are attached
|
* Libraries, JavaScript, CSS and other types of custom structures are attached
|
||||||
* to elements using the #attached property. The #attached property is an
|
* to elements using the #attached property. The #attached property is an
|
||||||
* associative array, where the keys are the the attachment types and the values
|
* associative array, where the keys are the attachment types and the values are
|
||||||
* are the attached data. For example:
|
* the attached data. For example:
|
||||||
* @code
|
* @code
|
||||||
* $build['#attached'] = array(
|
* $build['#attached'] = array(
|
||||||
* 'js' => array(drupal_get_path('module', 'taxonomy') . '/taxonomy.js'),
|
* 'js' => array(drupal_get_path('module', 'taxonomy') . '/taxonomy.js'),
|
||||||
@ -5260,8 +5343,6 @@ function drupal_cron_run() {
|
|||||||
foreach ($queues as $queue_name => $info) {
|
foreach ($queues as $queue_name => $info) {
|
||||||
DrupalQueue::get($queue_name)->createQueue();
|
DrupalQueue::get($queue_name)->createQueue();
|
||||||
}
|
}
|
||||||
// Register shutdown callback.
|
|
||||||
drupal_register_shutdown_function('drupal_cron_cleanup');
|
|
||||||
|
|
||||||
// Iterate through the modules calling their cron handlers (if any):
|
// Iterate through the modules calling their cron handlers (if any):
|
||||||
foreach (module_implements('cron') as $module) {
|
foreach (module_implements('cron') as $module) {
|
||||||
@ -5313,10 +5394,13 @@ function drupal_cron_run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shutdown function: Performs cron cleanup.
|
* DEPRECATED: Shutdown function: Performs cron cleanup.
|
||||||
*
|
*
|
||||||
* @see drupal_cron_run()
|
* This function is deprecated because the 'cron_semaphore' variable it
|
||||||
* @see drupal_register_shutdown_function()
|
* references no longer exists. It is therefore no longer used as a shutdown
|
||||||
|
* function by Drupal core.
|
||||||
|
*
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
function drupal_cron_cleanup() {
|
function drupal_cron_cleanup() {
|
||||||
// See if the semaphore is still locked.
|
// See if the semaphore is still locked.
|
||||||
@ -6641,10 +6725,10 @@ function drupal_array_set_nested_value(array &$array, array $parents, $value, $f
|
|||||||
* $value = drupal_array_get_nested_value($form, $parents);
|
* $value = drupal_array_get_nested_value($form, $parents);
|
||||||
* @endcode
|
* @endcode
|
||||||
*
|
*
|
||||||
* The return value will be NULL, regardless of whether the actual value is NULL
|
* A return value of NULL is ambiguous, and can mean either that the requested
|
||||||
* or whether the requested key does not exist. If it is required to know
|
* key does not exist, or that the actual value is NULL. If it is required to
|
||||||
* whether the nested array key actually exists, pass a third argument that is
|
* know whether the nested array key actually exists, pass a third argument that
|
||||||
* altered by reference:
|
* is altered by reference:
|
||||||
* @code
|
* @code
|
||||||
* $key_exists = NULL;
|
* $key_exists = NULL;
|
||||||
* $value = drupal_array_get_nested_value($form, $parents, $key_exists);
|
* $value = drupal_array_get_nested_value($form, $parents, $key_exists);
|
||||||
@ -7903,6 +7987,56 @@ function entity_prepare_view($entity_type, $entities, $langcode = NULL) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoke hook_entity_view_mode_alter().
|
||||||
|
*
|
||||||
|
* If adding a new entity similar to nodes, comments or users, you should invoke
|
||||||
|
* this function during the ENTITY_build_content() or ENTITY_view_multiple()
|
||||||
|
* phases of rendering to allow other modules to alter the view mode during this
|
||||||
|
* phase. This function needs to be called before field_attach_prepare_view() to
|
||||||
|
* ensure that the correct content is loaded by field API.
|
||||||
|
*
|
||||||
|
* @param $entity_type
|
||||||
|
* The type of entity, i.e. 'node', 'user'.
|
||||||
|
* @param $entities
|
||||||
|
* The entity objects which are being prepared for view, keyed by object ID.
|
||||||
|
* @param $view_mode
|
||||||
|
* The original view mode e.g. 'full', 'teaser'...
|
||||||
|
* @param $langcode
|
||||||
|
* (optional) A language code to be used for rendering. Defaults to the global
|
||||||
|
* content language of the current request.
|
||||||
|
* @return
|
||||||
|
* An associative array with arrays of entities keyed by view mode.
|
||||||
|
*
|
||||||
|
* @see hook_entity_view_mode_alter()
|
||||||
|
*/
|
||||||
|
function entity_view_mode_prepare($entity_type, $entities, $view_mode, $langcode = NULL) {
|
||||||
|
if (!isset($langcode)) {
|
||||||
|
$langcode = $GLOBALS['language_content']->language;
|
||||||
|
}
|
||||||
|
|
||||||
|
// To ensure hooks are never run after field_attach_prepare_view() only
|
||||||
|
// process items without the entity_view_prepared flag.
|
||||||
|
$entities_by_view_mode = array();
|
||||||
|
foreach ($entities as $id => $entity) {
|
||||||
|
$entity_view_mode = $view_mode;
|
||||||
|
if (empty($entity->entity_view_prepared)) {
|
||||||
|
|
||||||
|
// Allow modules to change the view mode.
|
||||||
|
$context = array(
|
||||||
|
'entity_type' => $entity_type,
|
||||||
|
'entity' => $entity,
|
||||||
|
'langcode' => $langcode,
|
||||||
|
);
|
||||||
|
drupal_alter('entity_view_mode', $entity_view_mode, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
$entities_by_view_mode[$entity_view_mode][$id] = $entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $entities_by_view_mode;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the URI elements of an entity.
|
* Returns the URI elements of an entity.
|
||||||
*
|
*
|
||||||
|
@ -736,7 +736,7 @@ abstract class DatabaseConnection extends PDO {
|
|||||||
// to expand it out into a comma-delimited set of placeholders.
|
// to expand it out into a comma-delimited set of placeholders.
|
||||||
foreach (array_filter($args, 'is_array') as $key => $data) {
|
foreach (array_filter($args, 'is_array') as $key => $data) {
|
||||||
$new_keys = array();
|
$new_keys = array();
|
||||||
foreach ($data as $i => $value) {
|
foreach (array_values($data) as $i => $value) {
|
||||||
// This assumes that there are no other placeholders that use the same
|
// This assumes that there are no other placeholders that use the same
|
||||||
// name. For example, if the array placeholder is defined as :example
|
// name. For example, if the array placeholder is defined as :example
|
||||||
// and there is already an :example_2 placeholder, this will generate
|
// and there is already an :example_2 placeholder, this will generate
|
||||||
@ -2832,7 +2832,7 @@ function db_drop_table($table) {
|
|||||||
* will be set to the value of the key in all rows. This is most useful for
|
* will be set to the value of the key in all rows. This is most useful for
|
||||||
* creating NOT NULL columns with no default value in existing tables.
|
* creating NOT NULL columns with no default value in existing tables.
|
||||||
* @param $keys_new
|
* @param $keys_new
|
||||||
* Optional keys and indexes specification to be created on the table along
|
* (optional) Keys and indexes specification to be created on the table along
|
||||||
* with adding the field. The format is the same as a table specification, but
|
* with adding the field. The format is the same as a table specification, but
|
||||||
* without the 'fields' element. If you are adding a type 'serial' field, you
|
* without the 'fields' element. If you are adding a type 'serial' field, you
|
||||||
* MUST specify at least one key or index including it in this array. See
|
* MUST specify at least one key or index including it in this array. See
|
||||||
@ -3012,7 +3012,7 @@ function db_drop_index($table, $name) {
|
|||||||
* @param $spec
|
* @param $spec
|
||||||
* The field specification for the new field.
|
* The field specification for the new field.
|
||||||
* @param $keys_new
|
* @param $keys_new
|
||||||
* Optional keys and indexes specification to be created on the table along
|
* (optional) Keys and indexes specification to be created on the table along
|
||||||
* with changing the field. The format is the same as a table specification
|
* with changing the field. The format is the same as a table specification
|
||||||
* but without the 'fields' element.
|
* but without the 'fields' element.
|
||||||
*/
|
*/
|
||||||
|
@ -36,6 +36,10 @@ class DatabaseConnection_mysql extends DatabaseConnection {
|
|||||||
// Default to TCP connection on port 3306.
|
// Default to TCP connection on port 3306.
|
||||||
$dsn = 'mysql:host=' . $connection_options['host'] . ';port=' . (empty($connection_options['port']) ? 3306 : $connection_options['port']);
|
$dsn = 'mysql:host=' . $connection_options['host'] . ';port=' . (empty($connection_options['port']) ? 3306 : $connection_options['port']);
|
||||||
}
|
}
|
||||||
|
// Character set is added to dsn to ensure PDO uses the proper character
|
||||||
|
// set when escaping. This has security implications. See
|
||||||
|
// https://www.drupal.org/node/1201452 for further discussion.
|
||||||
|
$dsn .= ';charset=utf8';
|
||||||
$dsn .= ';dbname=' . $connection_options['database'];
|
$dsn .= ';dbname=' . $connection_options['database'];
|
||||||
// Allow PDO options to be overridden.
|
// Allow PDO options to be overridden.
|
||||||
$connection_options += array(
|
$connection_options += array(
|
||||||
|
@ -40,7 +40,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$db_info = Database::getConnectionInfo();
|
$db_info = Database::getConnectionInfo();
|
||||||
$info['database'] = $db_info['default']['database'];
|
$info['database'] = $db_info[$this->connection->getTarget()]['database'];
|
||||||
$info['table'] = $table;
|
$info['table'] = $table;
|
||||||
}
|
}
|
||||||
return $info;
|
return $info;
|
||||||
@ -301,10 +301,10 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
|||||||
|
|
||||||
public function renameTable($table, $new_name) {
|
public function renameTable($table, $new_name) {
|
||||||
if (!$this->tableExists($table)) {
|
if (!$this->tableExists($table)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot rename %table to %table_new: table %table doesn't exist.", array('%table' => $table, '%table_new' => $new_name)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot rename @table to @table_new: table @table doesn't exist.", array('@table' => $table, '@table_new' => $new_name)));
|
||||||
}
|
}
|
||||||
if ($this->tableExists($new_name)) {
|
if ($this->tableExists($new_name)) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename %table to %table_new: table %table_new already exists.", array('%table' => $table, '%table_new' => $new_name)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot rename @table to @table_new: table @table_new already exists.", array('@table' => $table, '@table_new' => $new_name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$info = $this->getPrefixInfo($new_name);
|
$info = $this->getPrefixInfo($new_name);
|
||||||
@ -322,10 +322,10 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
|||||||
|
|
||||||
public function addField($table, $field, $spec, $keys_new = array()) {
|
public function addField($table, $field, $spec, $keys_new = array()) {
|
||||||
if (!$this->tableExists($table)) {
|
if (!$this->tableExists($table)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add field %table.%field: table doesn't exist.", array('%field' => $field, '%table' => $table)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add field @table.@field: table doesn't exist.", array('@field' => $field, '@table' => $table)));
|
||||||
}
|
}
|
||||||
if ($this->fieldExists($table, $field)) {
|
if ($this->fieldExists($table, $field)) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add field %table.%field: field already exists.", array('%field' => $field, '%table' => $table)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot add field @table.@field: field already exists.", array('@field' => $field, '@table' => $table)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$fixnull = FALSE;
|
$fixnull = FALSE;
|
||||||
@ -361,7 +361,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
|||||||
|
|
||||||
public function fieldSetDefault($table, $field, $default) {
|
public function fieldSetDefault($table, $field, $default) {
|
||||||
if (!$this->fieldExists($table, $field)) {
|
if (!$this->fieldExists($table, $field)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot set default value of field %table.%field: field doesn't exist.", array('%table' => $table, '%field' => $field)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot set default value of field @table.@field: field doesn't exist.", array('@table' => $table, '@field' => $field)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($default)) {
|
if (!isset($default)) {
|
||||||
@ -376,7 +376,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
|||||||
|
|
||||||
public function fieldSetNoDefault($table, $field) {
|
public function fieldSetNoDefault($table, $field) {
|
||||||
if (!$this->fieldExists($table, $field)) {
|
if (!$this->fieldExists($table, $field)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot remove default value of field %table.%field: field doesn't exist.", array('%table' => $table, '%field' => $field)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot remove default value of field @table.@field: field doesn't exist.", array('@table' => $table, '@field' => $field)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->connection->query('ALTER TABLE {' . $table . '} ALTER COLUMN `' . $field . '` DROP DEFAULT');
|
$this->connection->query('ALTER TABLE {' . $table . '} ALTER COLUMN `' . $field . '` DROP DEFAULT');
|
||||||
@ -391,10 +391,10 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
|||||||
|
|
||||||
public function addPrimaryKey($table, $fields) {
|
public function addPrimaryKey($table, $fields) {
|
||||||
if (!$this->tableExists($table)) {
|
if (!$this->tableExists($table)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add primary key to table %table: table doesn't exist.", array('%table' => $table)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add primary key to table @table: table doesn't exist.", array('@table' => $table)));
|
||||||
}
|
}
|
||||||
if ($this->indexExists($table, 'PRIMARY')) {
|
if ($this->indexExists($table, 'PRIMARY')) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add primary key to table %table: primary key already exists.", array('%table' => $table)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot add primary key to table @table: primary key already exists.", array('@table' => $table)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->connection->query('ALTER TABLE {' . $table . '} ADD PRIMARY KEY (' . $this->createKeySql($fields) . ')');
|
$this->connection->query('ALTER TABLE {' . $table . '} ADD PRIMARY KEY (' . $this->createKeySql($fields) . ')');
|
||||||
@ -411,10 +411,10 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
|||||||
|
|
||||||
public function addUniqueKey($table, $name, $fields) {
|
public function addUniqueKey($table, $name, $fields) {
|
||||||
if (!$this->tableExists($table)) {
|
if (!$this->tableExists($table)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add unique key %name to table %table: table doesn't exist.", array('%table' => $table, '%name' => $name)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add unique key @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name)));
|
||||||
}
|
}
|
||||||
if ($this->indexExists($table, $name)) {
|
if ($this->indexExists($table, $name)) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key %name to table %table: unique key already exists.", array('%table' => $table, '%name' => $name)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key @name to table @table: unique key already exists.", array('@table' => $table, '@name' => $name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->connection->query('ALTER TABLE {' . $table . '} ADD UNIQUE KEY `' . $name . '` (' . $this->createKeySql($fields) . ')');
|
$this->connection->query('ALTER TABLE {' . $table . '} ADD UNIQUE KEY `' . $name . '` (' . $this->createKeySql($fields) . ')');
|
||||||
@ -431,10 +431,10 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
|||||||
|
|
||||||
public function addIndex($table, $name, $fields) {
|
public function addIndex($table, $name, $fields) {
|
||||||
if (!$this->tableExists($table)) {
|
if (!$this->tableExists($table)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add index %name to table %table: table doesn't exist.", array('%table' => $table, '%name' => $name)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add index @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name)));
|
||||||
}
|
}
|
||||||
if ($this->indexExists($table, $name)) {
|
if ($this->indexExists($table, $name)) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add index %name to table %table: index already exists.", array('%table' => $table, '%name' => $name)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot add index @name to table @table: index already exists.", array('@table' => $table, '@name' => $name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->connection->query('ALTER TABLE {' . $table . '} ADD INDEX `' . $name . '` (' . $this->createKeySql($fields) . ')');
|
$this->connection->query('ALTER TABLE {' . $table . '} ADD INDEX `' . $name . '` (' . $this->createKeySql($fields) . ')');
|
||||||
@ -451,10 +451,10 @@ class DatabaseSchema_mysql extends DatabaseSchema {
|
|||||||
|
|
||||||
public function changeField($table, $field, $field_new, $spec, $keys_new = array()) {
|
public function changeField($table, $field, $field_new, $spec, $keys_new = array()) {
|
||||||
if (!$this->fieldExists($table, $field)) {
|
if (!$this->fieldExists($table, $field)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot change the definition of field %table.%name: field doesn't exist.", array('%table' => $table, '%name' => $field)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot change the definition of field @table.@name: field doesn't exist.", array('@table' => $table, '@name' => $field)));
|
||||||
}
|
}
|
||||||
if (($field != $field_new) && $this->fieldExists($table, $field_new)) {
|
if (($field != $field_new) && $this->fieldExists($table, $field_new)) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename field %table.%name to %name_new: target field already exists.", array('%table' => $table, '%name' => $field, '%name_new' => $field_new)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot rename field @table.@name to @name_new: target field already exists.", array('@table' => $table, '@name' => $field, '@name_new' => $field_new)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = 'ALTER TABLE {' . $table . '} CHANGE `' . $field . '` ' . $this->createFieldSql($field_new, $this->processField($spec));
|
$sql = 'ALTER TABLE {' . $table . '} CHANGE `' . $field . '` ' . $this->createFieldSql($field_new, $this->processField($spec));
|
||||||
|
@ -314,10 +314,10 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
|
|||||||
|
|
||||||
function renameTable($table, $new_name) {
|
function renameTable($table, $new_name) {
|
||||||
if (!$this->tableExists($table)) {
|
if (!$this->tableExists($table)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot rename %table to %table_new: table %table doesn't exist.", array('%table' => $table, '%table_new' => $new_name)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot rename @table to @table_new: table @table doesn't exist.", array('@table' => $table, '@table_new' => $new_name)));
|
||||||
}
|
}
|
||||||
if ($this->tableExists($new_name)) {
|
if ($this->tableExists($new_name)) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename %table to %table_new: table %table_new already exists.", array('%table' => $table, '%table_new' => $new_name)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot rename @table to @table_new: table @table_new already exists.", array('@table' => $table, '@table_new' => $new_name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the schema and tablename for the old table.
|
// Get the schema and tablename for the old table.
|
||||||
@ -351,10 +351,10 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
|
|||||||
|
|
||||||
public function addField($table, $field, $spec, $new_keys = array()) {
|
public function addField($table, $field, $spec, $new_keys = array()) {
|
||||||
if (!$this->tableExists($table)) {
|
if (!$this->tableExists($table)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add field %table.%field: table doesn't exist.", array('%field' => $field, '%table' => $table)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add field @table.@field: table doesn't exist.", array('@field' => $field, '@table' => $table)));
|
||||||
}
|
}
|
||||||
if ($this->fieldExists($table, $field)) {
|
if ($this->fieldExists($table, $field)) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add field %table.%field: field already exists.", array('%field' => $field, '%table' => $table)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot add field @table.@field: field already exists.", array('@field' => $field, '@table' => $table)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$fixnull = FALSE;
|
$fixnull = FALSE;
|
||||||
@ -393,7 +393,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
|
|||||||
|
|
||||||
public function fieldSetDefault($table, $field, $default) {
|
public function fieldSetDefault($table, $field, $default) {
|
||||||
if (!$this->fieldExists($table, $field)) {
|
if (!$this->fieldExists($table, $field)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot set default value of field %table.%field: field doesn't exist.", array('%table' => $table, '%field' => $field)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot set default value of field @table.@field: field doesn't exist.", array('@table' => $table, '@field' => $field)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($default)) {
|
if (!isset($default)) {
|
||||||
@ -408,7 +408,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
|
|||||||
|
|
||||||
public function fieldSetNoDefault($table, $field) {
|
public function fieldSetNoDefault($table, $field) {
|
||||||
if (!$this->fieldExists($table, $field)) {
|
if (!$this->fieldExists($table, $field)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot remove default value of field %table.%field: field doesn't exist.", array('%table' => $table, '%field' => $field)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot remove default value of field @table.@field: field doesn't exist.", array('@table' => $table, '@field' => $field)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->connection->query('ALTER TABLE {' . $table . '} ALTER COLUMN "' . $field . '" DROP DEFAULT');
|
$this->connection->query('ALTER TABLE {' . $table . '} ALTER COLUMN "' . $field . '" DROP DEFAULT');
|
||||||
@ -435,10 +435,10 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
|
|||||||
|
|
||||||
public function addPrimaryKey($table, $fields) {
|
public function addPrimaryKey($table, $fields) {
|
||||||
if (!$this->tableExists($table)) {
|
if (!$this->tableExists($table)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add primary key to table %table: table doesn't exist.", array('%table' => $table)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add primary key to table @table: table doesn't exist.", array('@table' => $table)));
|
||||||
}
|
}
|
||||||
if ($this->constraintExists($table, 'pkey')) {
|
if ($this->constraintExists($table, 'pkey')) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add primary key to table %table: primary key already exists.", array('%table' => $table)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot add primary key to table @table: primary key already exists.", array('@table' => $table)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->connection->query('ALTER TABLE {' . $table . '} ADD PRIMARY KEY (' . implode(',', $fields) . ')');
|
$this->connection->query('ALTER TABLE {' . $table . '} ADD PRIMARY KEY (' . implode(',', $fields) . ')');
|
||||||
@ -455,10 +455,10 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
|
|||||||
|
|
||||||
function addUniqueKey($table, $name, $fields) {
|
function addUniqueKey($table, $name, $fields) {
|
||||||
if (!$this->tableExists($table)) {
|
if (!$this->tableExists($table)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add unique key %name to table %table: table doesn't exist.", array('%table' => $table, '%name' => $name)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add unique key @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name)));
|
||||||
}
|
}
|
||||||
if ($this->constraintExists($table, $name . '_key')) {
|
if ($this->constraintExists($table, $name . '_key')) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key %name to table %table: unique key already exists.", array('%table' => $table, '%name' => $name)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key @name to table @table: unique key already exists.", array('@table' => $table, '@name' => $name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->connection->query('ALTER TABLE {' . $table . '} ADD CONSTRAINT "' . $this->prefixNonTable($table, $name, 'key') . '" UNIQUE (' . implode(',', $fields) . ')');
|
$this->connection->query('ALTER TABLE {' . $table . '} ADD CONSTRAINT "' . $this->prefixNonTable($table, $name, 'key') . '" UNIQUE (' . implode(',', $fields) . ')');
|
||||||
@ -475,10 +475,10 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
|
|||||||
|
|
||||||
public function addIndex($table, $name, $fields) {
|
public function addIndex($table, $name, $fields) {
|
||||||
if (!$this->tableExists($table)) {
|
if (!$this->tableExists($table)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add index %name to table %table: table doesn't exist.", array('%table' => $table, '%name' => $name)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add index @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name)));
|
||||||
}
|
}
|
||||||
if ($this->indexExists($table, $name)) {
|
if ($this->indexExists($table, $name)) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add index %name to table %table: index already exists.", array('%table' => $table, '%name' => $name)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot add index @name to table @table: index already exists.", array('@table' => $table, '@name' => $name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->connection->query($this->_createIndexSql($table, $name, $fields));
|
$this->connection->query($this->_createIndexSql($table, $name, $fields));
|
||||||
@ -495,10 +495,10 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
|
|||||||
|
|
||||||
public function changeField($table, $field, $field_new, $spec, $new_keys = array()) {
|
public function changeField($table, $field, $field_new, $spec, $new_keys = array()) {
|
||||||
if (!$this->fieldExists($table, $field)) {
|
if (!$this->fieldExists($table, $field)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot change the definition of field %table.%name: field doesn't exist.", array('%table' => $table, '%name' => $field)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot change the definition of field @table.@name: field doesn't exist.", array('@table' => $table, '@name' => $field)));
|
||||||
}
|
}
|
||||||
if (($field != $field_new) && $this->fieldExists($table, $field_new)) {
|
if (($field != $field_new) && $this->fieldExists($table, $field_new)) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename field %table.%name to %name_new: target field already exists.", array('%table' => $table, '%name' => $field, '%name_new' => $field_new)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot rename field @table.@name to @name_new: target field already exists.", array('@table' => $table, '@name' => $field, '@name_new' => $field_new)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$spec = $this->processField($spec);
|
$spec = $this->processField($spec);
|
||||||
|
@ -1694,7 +1694,7 @@ class DatabaseCondition implements QueryConditionInterface, Countable {
|
|||||||
* Implements Countable::count().
|
* Implements Countable::count().
|
||||||
*
|
*
|
||||||
* Returns the size of this conditional. The size of the conditional is the
|
* Returns the size of this conditional. The size of the conditional is the
|
||||||
* size of its conditional array minus one, because one element is the the
|
* size of its conditional array minus one, because one element is the
|
||||||
* conjunction.
|
* conjunction.
|
||||||
*/
|
*/
|
||||||
public function count() {
|
public function count() {
|
||||||
|
@ -416,7 +416,7 @@ abstract class DatabaseSchema implements QueryPlaceholderInterface {
|
|||||||
* This is most useful for creating NOT NULL columns with no default
|
* This is most useful for creating NOT NULL columns with no default
|
||||||
* value in existing tables.
|
* value in existing tables.
|
||||||
* @param $keys_new
|
* @param $keys_new
|
||||||
* Optional keys and indexes specification to be created on the
|
* (optional) Keys and indexes specification to be created on the
|
||||||
* table along with adding the field. The format is the same as a
|
* table along with adding the field. The format is the same as a
|
||||||
* table specification but without the 'fields' element. If you are
|
* table specification but without the 'fields' element. If you are
|
||||||
* adding a type 'serial' field, you MUST specify at least one key
|
* adding a type 'serial' field, you MUST specify at least one key
|
||||||
@ -630,7 +630,7 @@ abstract class DatabaseSchema implements QueryPlaceholderInterface {
|
|||||||
* @param $spec
|
* @param $spec
|
||||||
* The field specification for the new field.
|
* The field specification for the new field.
|
||||||
* @param $keys_new
|
* @param $keys_new
|
||||||
* Optional keys and indexes specification to be created on the
|
* (optional) Keys and indexes specification to be created on the
|
||||||
* table along with changing the field. The format is the same as a
|
* table along with changing the field. The format is the same as a
|
||||||
* table specification but without the 'fields' element.
|
* table specification but without the 'fields' element.
|
||||||
*
|
*
|
||||||
@ -654,7 +654,7 @@ abstract class DatabaseSchema implements QueryPlaceholderInterface {
|
|||||||
*/
|
*/
|
||||||
public function createTable($name, $table) {
|
public function createTable($name, $table) {
|
||||||
if ($this->tableExists($name)) {
|
if ($this->tableExists($name)) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t('Table %name already exists.', array('%name' => $name)));
|
throw new DatabaseSchemaObjectExistsException(t('Table @name already exists.', array('@name' => $name)));
|
||||||
}
|
}
|
||||||
$statements = $this->createTableSql($name, $table);
|
$statements = $this->createTableSql($name, $table);
|
||||||
foreach ($statements as $statement) {
|
foreach ($statements as $statement) {
|
||||||
|
@ -377,7 +377,8 @@ interface SelectQueryInterface extends QueryConditionInterface, QueryAlterableIn
|
|||||||
* @param $field
|
* @param $field
|
||||||
* The field on which to order.
|
* The field on which to order.
|
||||||
* @param $direction
|
* @param $direction
|
||||||
* The direction to sort. Legal values are "ASC" and "DESC".
|
* The direction to sort. Legal values are "ASC" and "DESC". Any other value
|
||||||
|
* will be converted to "ASC".
|
||||||
* @return SelectQueryInterface
|
* @return SelectQueryInterface
|
||||||
* The called object.
|
* The called object.
|
||||||
*/
|
*/
|
||||||
@ -1384,6 +1385,8 @@ class SelectQuery extends Query implements SelectQueryInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function orderBy($field, $direction = 'ASC') {
|
public function orderBy($field, $direction = 'ASC') {
|
||||||
|
// Only allow ASC and DESC, default to ASC.
|
||||||
|
$direction = strtoupper($direction) == 'DESC' ? 'DESC' : 'ASC';
|
||||||
$this->order[$field] = $direction;
|
$this->order[$field] = $direction;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -232,10 +232,10 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
|||||||
|
|
||||||
public function renameTable($table, $new_name) {
|
public function renameTable($table, $new_name) {
|
||||||
if (!$this->tableExists($table)) {
|
if (!$this->tableExists($table)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot rename %table to %table_new: table %table doesn't exist.", array('%table' => $table, '%table_new' => $new_name)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot rename @table to @table_new: table @table doesn't exist.", array('@table' => $table, '@table_new' => $new_name)));
|
||||||
}
|
}
|
||||||
if ($this->tableExists($new_name)) {
|
if ($this->tableExists($new_name)) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename %table to %table_new: table %table_new already exists.", array('%table' => $table, '%table_new' => $new_name)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot rename @table to @table_new: table @table_new already exists.", array('@table' => $table, '@table_new' => $new_name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$schema = $this->introspectSchema($table);
|
$schema = $this->introspectSchema($table);
|
||||||
@ -278,10 +278,10 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
|||||||
|
|
||||||
public function addField($table, $field, $specification, $keys_new = array()) {
|
public function addField($table, $field, $specification, $keys_new = array()) {
|
||||||
if (!$this->tableExists($table)) {
|
if (!$this->tableExists($table)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add field %table.%field: table doesn't exist.", array('%field' => $field, '%table' => $table)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add field @table.@field: table doesn't exist.", array('@field' => $field, '@table' => $table)));
|
||||||
}
|
}
|
||||||
if ($this->fieldExists($table, $field)) {
|
if ($this->fieldExists($table, $field)) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add field %table.%field: field already exists.", array('%field' => $field, '%table' => $table)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot add field @table.@field: field already exists.", array('@field' => $field, '@table' => $table)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// SQLite doesn't have a full-featured ALTER TABLE statement. It only
|
// SQLite doesn't have a full-featured ALTER TABLE statement. It only
|
||||||
@ -494,10 +494,10 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
|||||||
|
|
||||||
public function changeField($table, $field, $field_new, $spec, $keys_new = array()) {
|
public function changeField($table, $field, $field_new, $spec, $keys_new = array()) {
|
||||||
if (!$this->fieldExists($table, $field)) {
|
if (!$this->fieldExists($table, $field)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot change the definition of field %table.%name: field doesn't exist.", array('%table' => $table, '%name' => $field)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot change the definition of field @table.@name: field doesn't exist.", array('@table' => $table, '@name' => $field)));
|
||||||
}
|
}
|
||||||
if (($field != $field_new) && $this->fieldExists($table, $field_new)) {
|
if (($field != $field_new) && $this->fieldExists($table, $field_new)) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot rename field %table.%name to %name_new: target field already exists.", array('%table' => $table, '%name' => $field, '%name_new' => $field_new)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot rename field @table.@name to @name_new: target field already exists.", array('@table' => $table, '@name' => $field, '@name_new' => $field_new)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$old_schema = $this->introspectSchema($table);
|
$old_schema = $this->introspectSchema($table);
|
||||||
@ -559,10 +559,10 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
|||||||
|
|
||||||
public function addIndex($table, $name, $fields) {
|
public function addIndex($table, $name, $fields) {
|
||||||
if (!$this->tableExists($table)) {
|
if (!$this->tableExists($table)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add index %name to table %table: table doesn't exist.", array('%table' => $table, '%name' => $name)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add index @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name)));
|
||||||
}
|
}
|
||||||
if ($this->indexExists($table, $name)) {
|
if ($this->indexExists($table, $name)) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add index %name to table %table: index already exists.", array('%table' => $table, '%name' => $name)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot add index @name to table @table: index already exists.", array('@table' => $table, '@name' => $name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$schema['indexes'][$name] = $fields;
|
$schema['indexes'][$name] = $fields;
|
||||||
@ -591,10 +591,10 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
|||||||
|
|
||||||
public function addUniqueKey($table, $name, $fields) {
|
public function addUniqueKey($table, $name, $fields) {
|
||||||
if (!$this->tableExists($table)) {
|
if (!$this->tableExists($table)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add unique key %name to table %table: table doesn't exist.", array('%table' => $table, '%name' => $name)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add unique key @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name)));
|
||||||
}
|
}
|
||||||
if ($this->indexExists($table, $name)) {
|
if ($this->indexExists($table, $name)) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key %name to table %table: unique key already exists.", array('%table' => $table, '%name' => $name)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key @name to table @table: unique key already exists.", array('@table' => $table, '@name' => $name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$schema['unique keys'][$name] = $fields;
|
$schema['unique keys'][$name] = $fields;
|
||||||
@ -617,14 +617,14 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
|||||||
|
|
||||||
public function addPrimaryKey($table, $fields) {
|
public function addPrimaryKey($table, $fields) {
|
||||||
if (!$this->tableExists($table)) {
|
if (!$this->tableExists($table)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add primary key to table %table: table doesn't exist.", array('%table' => $table)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add primary key to table @table: table doesn't exist.", array('@table' => $table)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$old_schema = $this->introspectSchema($table);
|
$old_schema = $this->introspectSchema($table);
|
||||||
$new_schema = $old_schema;
|
$new_schema = $old_schema;
|
||||||
|
|
||||||
if (!empty($new_schema['primary key'])) {
|
if (!empty($new_schema['primary key'])) {
|
||||||
throw new DatabaseSchemaObjectExistsException(t("Cannot add primary key to table %table: primary key already exists.", array('%table' => $table)));
|
throw new DatabaseSchemaObjectExistsException(t("Cannot add primary key to table @table: primary key already exists.", array('@table' => $table)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$new_schema['primary key'] = $fields;
|
$new_schema['primary key'] = $fields;
|
||||||
@ -646,7 +646,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
|||||||
|
|
||||||
public function fieldSetDefault($table, $field, $default) {
|
public function fieldSetDefault($table, $field, $default) {
|
||||||
if (!$this->fieldExists($table, $field)) {
|
if (!$this->fieldExists($table, $field)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot set default value of field %table.%field: field doesn't exist.", array('%table' => $table, '%field' => $field)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot set default value of field @table.@field: field doesn't exist.", array('@table' => $table, '@field' => $field)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$old_schema = $this->introspectSchema($table);
|
$old_schema = $this->introspectSchema($table);
|
||||||
@ -658,7 +658,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
|||||||
|
|
||||||
public function fieldSetNoDefault($table, $field) {
|
public function fieldSetNoDefault($table, $field) {
|
||||||
if (!$this->fieldExists($table, $field)) {
|
if (!$this->fieldExists($table, $field)) {
|
||||||
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot remove default value of field %table.%field: field doesn't exist.", array('%table' => $table, '%field' => $field)));
|
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot remove default value of field @table.@field: field doesn't exist.", array('@table' => $table, '@field' => $field)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$old_schema = $this->introspectSchema($table);
|
$old_schema = $this->introspectSchema($table);
|
||||||
|
@ -28,7 +28,9 @@ interface DrupalEntityControllerInterface {
|
|||||||
* @param $ids
|
* @param $ids
|
||||||
* An array of entity IDs, or FALSE to load all entities.
|
* An array of entity IDs, or FALSE to load all entities.
|
||||||
* @param $conditions
|
* @param $conditions
|
||||||
* An array of conditions in the form 'field' => $value.
|
* An array of conditions. Keys are field names on the entity's base table.
|
||||||
|
* Values will be compared for equality. All the comparisons will be ANDed
|
||||||
|
* together. This parameter is deprecated; use an EntityFieldQuery instead.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* An array of entity objects indexed by their ids. When no results are
|
* An array of entity objects indexed by their ids. When no results are
|
||||||
@ -46,7 +48,7 @@ interface DrupalEntityControllerInterface {
|
|||||||
class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
|
class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static cache of entities.
|
* Static cache of entities, keyed by entity ID.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
@ -236,7 +238,9 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
|
|||||||
* @param $ids
|
* @param $ids
|
||||||
* An array of entity IDs, or FALSE to load all entities.
|
* An array of entity IDs, or FALSE to load all entities.
|
||||||
* @param $conditions
|
* @param $conditions
|
||||||
* An array of conditions in the form 'field' => $value.
|
* An array of conditions. Keys are field names on the entity's base table.
|
||||||
|
* Values will be compared for equality. All the comparisons will be ANDed
|
||||||
|
* together. This parameter is deprecated; use an EntityFieldQuery instead.
|
||||||
* @param $revision_id
|
* @param $revision_id
|
||||||
* The ID of the revision to load, or FALSE if this query is asking for the
|
* The ID of the revision to load, or FALSE if this query is asking for the
|
||||||
* most current revision(s).
|
* most current revision(s).
|
||||||
|
@ -1152,7 +1152,7 @@ function file_munge_filename($filename, $extensions, $alerts = TRUE) {
|
|||||||
// Remove any null bytes. See http://php.net/manual/security.filesystem.nullbytes.php
|
// Remove any null bytes. See http://php.net/manual/security.filesystem.nullbytes.php
|
||||||
$filename = str_replace(chr(0), '', $filename);
|
$filename = str_replace(chr(0), '', $filename);
|
||||||
|
|
||||||
$whitelist = array_unique(explode(' ', trim($extensions)));
|
$whitelist = array_unique(explode(' ', strtolower(trim($extensions))));
|
||||||
|
|
||||||
// Split the filename up by periods. The first part becomes the basename
|
// Split the filename up by periods. The first part becomes the basename
|
||||||
// the last part the final extension.
|
// the last part the final extension.
|
||||||
@ -1165,7 +1165,7 @@ function file_munge_filename($filename, $extensions, $alerts = TRUE) {
|
|||||||
// of allowed extensions.
|
// of allowed extensions.
|
||||||
foreach ($filename_parts as $filename_part) {
|
foreach ($filename_parts as $filename_part) {
|
||||||
$new_filename .= '.' . $filename_part;
|
$new_filename .= '.' . $filename_part;
|
||||||
if (!in_array($filename_part, $whitelist) && preg_match("/^[a-zA-Z]{2,5}\d?$/", $filename_part)) {
|
if (!in_array(strtolower($filename_part), $whitelist) && preg_match("/^[a-zA-Z]{2,5}\d?$/", $filename_part)) {
|
||||||
$new_filename .= '_';
|
$new_filename .= '_';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1559,7 +1559,7 @@ function file_save_upload($form_field_name, $validators = array(), $destination
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add in our check of the the file name length.
|
// Add in our check of the file name length.
|
||||||
$validators['file_validate_name_length'] = array();
|
$validators['file_validate_name_length'] = array();
|
||||||
|
|
||||||
// Call the validation functions specified by this function's caller.
|
// Call the validation functions specified by this function's caller.
|
||||||
@ -1729,8 +1729,6 @@ function file_validate_extensions(stdClass $file, $extensions) {
|
|||||||
/**
|
/**
|
||||||
* Checks that the file's size is below certain limits.
|
* Checks that the file's size is below certain limits.
|
||||||
*
|
*
|
||||||
* This check is not enforced for the user #1.
|
|
||||||
*
|
|
||||||
* @param $file
|
* @param $file
|
||||||
* A Drupal file object.
|
* A Drupal file object.
|
||||||
* @param $file_limit
|
* @param $file_limit
|
||||||
@ -1748,20 +1746,17 @@ function file_validate_extensions(stdClass $file, $extensions) {
|
|||||||
*/
|
*/
|
||||||
function file_validate_size(stdClass $file, $file_limit = 0, $user_limit = 0) {
|
function file_validate_size(stdClass $file, $file_limit = 0, $user_limit = 0) {
|
||||||
global $user;
|
global $user;
|
||||||
|
|
||||||
$errors = array();
|
$errors = array();
|
||||||
|
|
||||||
// Bypass validation for uid = 1.
|
if ($file_limit && $file->filesize > $file_limit) {
|
||||||
if ($user->uid != 1) {
|
$errors[] = t('The file is %filesize exceeding the maximum file size of %maxsize.', array('%filesize' => format_size($file->filesize), '%maxsize' => format_size($file_limit)));
|
||||||
if ($file_limit && $file->filesize > $file_limit) {
|
|
||||||
$errors[] = t('The file is %filesize exceeding the maximum file size of %maxsize.', array('%filesize' => format_size($file->filesize), '%maxsize' => format_size($file_limit)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save a query by only calling file_space_used() when a limit is provided.
|
|
||||||
if ($user_limit && (file_space_used($user->uid) + $file->filesize) > $user_limit) {
|
|
||||||
$errors[] = t('The file is %filesize which would exceed your disk quota of %quota.', array('%filesize' => format_size($file->filesize), '%quota' => format_size($user_limit)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save a query by only calling file_space_used() when a limit is provided.
|
||||||
|
if ($user_limit && (file_space_used($user->uid) + $file->filesize) > $user_limit) {
|
||||||
|
$errors[] = t('The file is %filesize which would exceed your disk quota of %quota.', array('%filesize' => format_size($file->filesize), '%quota' => format_size($user_limit)));
|
||||||
|
}
|
||||||
|
|
||||||
return $errors;
|
return $errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1999,23 +1994,7 @@ function file_download() {
|
|||||||
$target = implode('/', $args);
|
$target = implode('/', $args);
|
||||||
$uri = $scheme . '://' . $target;
|
$uri = $scheme . '://' . $target;
|
||||||
if (file_stream_wrapper_valid_scheme($scheme) && file_exists($uri)) {
|
if (file_stream_wrapper_valid_scheme($scheme) && file_exists($uri)) {
|
||||||
// Let other modules provide headers and controls access to the file.
|
$headers = file_download_headers($uri);
|
||||||
// module_invoke_all() uses array_merge_recursive() which merges header
|
|
||||||
// values into a new array. To avoid that and allow modules to override
|
|
||||||
// headers instead, use array_merge() to merge the returned arrays.
|
|
||||||
$headers = array();
|
|
||||||
foreach (module_implements('file_download') as $module) {
|
|
||||||
$function = $module . '_file_download';
|
|
||||||
$result = $function($uri);
|
|
||||||
if ($result == -1) {
|
|
||||||
// Throw away the headers received so far.
|
|
||||||
$headers = array();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (isset($result) && is_array($result)) {
|
|
||||||
$headers = array_merge($headers, $result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (count($headers)) {
|
if (count($headers)) {
|
||||||
file_transfer($uri, $headers);
|
file_transfer($uri, $headers);
|
||||||
}
|
}
|
||||||
@ -2027,6 +2006,69 @@ function file_download() {
|
|||||||
drupal_exit();
|
drupal_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves headers for a private file download.
|
||||||
|
*
|
||||||
|
* Calls all module implementations of hook_file_download() to retrieve headers
|
||||||
|
* for files by the module that originally provided the file. The presence of
|
||||||
|
* returned headers indicates the current user has access to the file.
|
||||||
|
*
|
||||||
|
* @param $uri
|
||||||
|
* The URI for the file whose headers should be retrieved.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* If access is allowed, headers for the file, suitable for passing to
|
||||||
|
* file_transfer(). If access is not allowed, an empty array will be returned.
|
||||||
|
*
|
||||||
|
* @see file_transfer()
|
||||||
|
* @see file_download_access()
|
||||||
|
* @see hook_file_downlaod()
|
||||||
|
*/
|
||||||
|
function file_download_headers($uri) {
|
||||||
|
// Let other modules provide headers and control access to the file.
|
||||||
|
// module_invoke_all() uses array_merge_recursive() which merges header
|
||||||
|
// values into a new array. To avoid that and allow modules to override
|
||||||
|
// headers instead, use array_merge() to merge the returned arrays.
|
||||||
|
$headers = array();
|
||||||
|
foreach (module_implements('file_download') as $module) {
|
||||||
|
$function = $module . '_file_download';
|
||||||
|
$result = $function($uri);
|
||||||
|
if ($result == -1) {
|
||||||
|
// Throw away the headers received so far.
|
||||||
|
$headers = array();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (isset($result) && is_array($result)) {
|
||||||
|
$headers = array_merge($headers, $result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that the current user has access to a particular file.
|
||||||
|
*
|
||||||
|
* The return value of this function hinges on the return value from
|
||||||
|
* file_download_headers(), which is the function responsible for collecting
|
||||||
|
* access information through hook_file_download().
|
||||||
|
*
|
||||||
|
* If immediately transferring the file to the browser and the headers will
|
||||||
|
* need to be retrieved, the return value of file_download_headers() should be
|
||||||
|
* used to determine access directly, so that access checks will not be run
|
||||||
|
* twice.
|
||||||
|
*
|
||||||
|
* @param $uri
|
||||||
|
* The URI for the file whose access should be retrieved.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* Boolean TRUE if access is allowed. FALSE if access is not allowed.
|
||||||
|
*
|
||||||
|
* @see file_download_headers()
|
||||||
|
* @see hook_file_download()
|
||||||
|
*/
|
||||||
|
function file_download_access($uri) {
|
||||||
|
return count(file_download_headers($uri)) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds all files that match a given mask in a given directory.
|
* Finds all files that match a given mask in a given directory.
|
||||||
|
@ -43,6 +43,7 @@ function file_default_mimetype_mapping() {
|
|||||||
4 => 'application/cap',
|
4 => 'application/cap',
|
||||||
5 => 'application/cu-seeme',
|
5 => 'application/cu-seeme',
|
||||||
6 => 'application/dsptype',
|
6 => 'application/dsptype',
|
||||||
|
350 => 'application/epub+zip',
|
||||||
7 => 'application/hta',
|
7 => 'application/hta',
|
||||||
8 => 'application/java-archive',
|
8 => 'application/java-archive',
|
||||||
9 => 'application/java-serialized-object',
|
9 => 'application/java-serialized-object',
|
||||||
@ -64,6 +65,7 @@ function file_default_mimetype_mapping() {
|
|||||||
25 => 'application/rss+xml',
|
25 => 'application/rss+xml',
|
||||||
26 => 'application/rtf',
|
26 => 'application/rtf',
|
||||||
27 => 'application/smil',
|
27 => 'application/smil',
|
||||||
|
349 => 'application/vnd.amazon.ebook',
|
||||||
28 => 'application/vnd.cinderella',
|
28 => 'application/vnd.cinderella',
|
||||||
29 => 'application/vnd.google-earth.kml+xml',
|
29 => 'application/vnd.google-earth.kml+xml',
|
||||||
30 => 'application/vnd.google-earth.kmz',
|
30 => 'application/vnd.google-earth.kmz',
|
||||||
@ -183,6 +185,8 @@ function file_default_mimetype_mapping() {
|
|||||||
144 => 'application/x-lzx',
|
144 => 'application/x-lzx',
|
||||||
145 => 'application/x-maker',
|
145 => 'application/x-maker',
|
||||||
146 => 'application/x-mif',
|
146 => 'application/x-mif',
|
||||||
|
351 => 'application/x-mobipocket-ebook',
|
||||||
|
352 => 'application/x-mobipocket-ebook',
|
||||||
147 => 'application/x-ms-wmd',
|
147 => 'application/x-ms-wmd',
|
||||||
148 => 'application/x-ms-wmz',
|
148 => 'application/x-ms-wmz',
|
||||||
149 => 'application/x-msdos-program',
|
149 => 'application/x-msdos-program',
|
||||||
@ -228,8 +232,10 @@ function file_default_mimetype_mapping() {
|
|||||||
188 => 'audio/mpeg',
|
188 => 'audio/mpeg',
|
||||||
189 => 'audio/ogg',
|
189 => 'audio/ogg',
|
||||||
190 => 'audio/prs.sid',
|
190 => 'audio/prs.sid',
|
||||||
|
356 => 'audio/webm',
|
||||||
191 => 'audio/x-aiff',
|
191 => 'audio/x-aiff',
|
||||||
192 => 'audio/x-gsm',
|
192 => 'audio/x-gsm',
|
||||||
|
354 => 'audio/x-matroska',
|
||||||
193 => 'audio/x-mpegurl',
|
193 => 'audio/x-mpegurl',
|
||||||
194 => 'audio/x-ms-wax',
|
194 => 'audio/x-ms-wax',
|
||||||
195 => 'audio/x-ms-wma',
|
195 => 'audio/x-ms-wma',
|
||||||
@ -301,6 +307,7 @@ function file_default_mimetype_mapping() {
|
|||||||
261 => 'image/vnd.djvu',
|
261 => 'image/vnd.djvu',
|
||||||
262 => 'image/vnd.microsoft.icon',
|
262 => 'image/vnd.microsoft.icon',
|
||||||
263 => 'image/vnd.wap.wbmp',
|
263 => 'image/vnd.wap.wbmp',
|
||||||
|
355 => 'image/webp',
|
||||||
264 => 'image/x-cmu-raster',
|
264 => 'image/x-cmu-raster',
|
||||||
265 => 'image/x-coreldraw',
|
265 => 'image/x-coreldraw',
|
||||||
266 => 'image/x-coreldrawpattern',
|
266 => 'image/x-coreldrawpattern',
|
||||||
@ -337,6 +344,7 @@ function file_default_mimetype_mapping() {
|
|||||||
297 => 'text/vnd.sun.j2me.app-descriptor',
|
297 => 'text/vnd.sun.j2me.app-descriptor',
|
||||||
298 => 'text/vnd.wap.wml',
|
298 => 'text/vnd.wap.wml',
|
||||||
299 => 'text/vnd.wap.wmlscript',
|
299 => 'text/vnd.wap.wmlscript',
|
||||||
|
358 => 'text/vtt',
|
||||||
300 => 'text/x-bibtex',
|
300 => 'text/x-bibtex',
|
||||||
301 => 'text/x-boo',
|
301 => 'text/x-boo',
|
||||||
302 => 'text/x-c++hdr',
|
302 => 'text/x-c++hdr',
|
||||||
@ -371,9 +379,11 @@ function file_default_mimetype_mapping() {
|
|||||||
331 => 'video/ogg',
|
331 => 'video/ogg',
|
||||||
332 => 'video/quicktime',
|
332 => 'video/quicktime',
|
||||||
333 => 'video/vnd.mpegurl',
|
333 => 'video/vnd.mpegurl',
|
||||||
|
357 => 'video/webm',
|
||||||
347 => 'video/x-flv',
|
347 => 'video/x-flv',
|
||||||
334 => 'video/x-la-asf',
|
334 => 'video/x-la-asf',
|
||||||
348 => 'video/x-m4v',
|
348 => 'video/x-m4v',
|
||||||
|
353 => 'video/x-matroska',
|
||||||
335 => 'video/x-mng',
|
335 => 'video/x-mng',
|
||||||
336 => 'video/x-ms-asf',
|
336 => 'video/x-ms-asf',
|
||||||
337 => 'video/x-ms-wm',
|
337 => 'video/x-ms-wm',
|
||||||
@ -854,6 +864,16 @@ function file_default_mimetype_mapping() {
|
|||||||
'f4b' => 346,
|
'f4b' => 346,
|
||||||
'flv' => 347,
|
'flv' => 347,
|
||||||
'm4v' => 348,
|
'm4v' => 348,
|
||||||
|
'azw' => 349,
|
||||||
|
'epub' => 350,
|
||||||
|
'mobi' => 351,
|
||||||
|
'prc' => 352,
|
||||||
|
'mkv' => 353,
|
||||||
|
'mka' => 354,
|
||||||
|
'webp' => 355,
|
||||||
|
'weba' => 356,
|
||||||
|
'webm' => 357,
|
||||||
|
'vtt' => 358,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,8 @@ class FileTransferSSH extends FileTransfer implements FileTransferChmodInterface
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
throw new FileTransferException('Cannot check @path.', NULL, array('@path' => $path));
|
throw new FileTransferException('Cannot check @path.', NULL, array('@path' => $path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,7 +86,8 @@ class FileTransferSSH extends FileTransfer implements FileTransferChmodInterface
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
throw new FileTransferException('Cannot check @path.', NULL, array('@path' => $path));
|
throw new FileTransferException('Cannot check @path.', NULL, array('@path' => $path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -938,7 +938,7 @@ function drupal_process_form($form_id, &$form, &$form_state) {
|
|||||||
// after the batch is processed.
|
// after the batch is processed.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set a flag to indicate the the form has been processed and executed.
|
// Set a flag to indicate that the form has been processed and executed.
|
||||||
$form_state['executed'] = TRUE;
|
$form_state['executed'] = TRUE;
|
||||||
|
|
||||||
// Redirect the form based on values in $form_state.
|
// Redirect the form based on values in $form_state.
|
||||||
@ -2451,6 +2451,17 @@ function form_type_password_confirm_value($element, $input = FALSE) {
|
|||||||
$element += array('#default_value' => array());
|
$element += array('#default_value' => array());
|
||||||
return $element['#default_value'] + array('pass1' => '', 'pass2' => '');
|
return $element['#default_value'] + array('pass1' => '', 'pass2' => '');
|
||||||
}
|
}
|
||||||
|
$value = array('pass1' => '', 'pass2' => '');
|
||||||
|
// Throw out all invalid array keys; we only allow pass1 and pass2.
|
||||||
|
foreach ($value as $allowed_key => $default) {
|
||||||
|
// These should be strings, but allow other scalars since they might be
|
||||||
|
// valid input in programmatic form submissions. Any nested array values
|
||||||
|
// are ignored.
|
||||||
|
if (isset($input[$allowed_key]) && is_scalar($input[$allowed_key])) {
|
||||||
|
$value[$allowed_key] = (string) $input[$allowed_key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2494,6 +2505,27 @@ function form_type_select_value($element, $input = FALSE) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the value for a textarea form element.
|
||||||
|
*
|
||||||
|
* @param array $element
|
||||||
|
* The form element whose value is being populated.
|
||||||
|
* @param mixed $input
|
||||||
|
* The incoming input to populate the form element. If this is FALSE,
|
||||||
|
* the element's default value should be returned.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The data that will appear in the $element_state['values'] collection
|
||||||
|
* for this element. Return nothing to use the default.
|
||||||
|
*/
|
||||||
|
function form_type_textarea_value($element, $input = FALSE) {
|
||||||
|
if ($input !== FALSE) {
|
||||||
|
// This should be a string, but allow other scalars since they might be
|
||||||
|
// valid input in programmatic form submissions.
|
||||||
|
return is_scalar($input) ? (string) $input : '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the value for a textfield form element.
|
* Determines the value for a textfield form element.
|
||||||
*
|
*
|
||||||
@ -2509,9 +2541,12 @@ function form_type_select_value($element, $input = FALSE) {
|
|||||||
*/
|
*/
|
||||||
function form_type_textfield_value($element, $input = FALSE) {
|
function form_type_textfield_value($element, $input = FALSE) {
|
||||||
if ($input !== FALSE && $input !== NULL) {
|
if ($input !== FALSE && $input !== NULL) {
|
||||||
// Equate $input to the form value to ensure it's marked for
|
// This should be a string, but allow other scalars since they might be
|
||||||
// validation.
|
// valid input in programmatic form submissions.
|
||||||
return str_replace(array("\r", "\n"), '', $input);
|
if (!is_scalar($input)) {
|
||||||
|
$input = '';
|
||||||
|
}
|
||||||
|
return str_replace(array("\r", "\n"), '', (string) $input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2699,17 +2734,43 @@ function theme_select($variables) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a select form element's options array into HTML.
|
* Converts an array of options into HTML, for use in select list form elements.
|
||||||
*
|
*
|
||||||
* @param $element
|
* This function calls itself recursively to obtain the values for each optgroup
|
||||||
* An associative array containing the properties of the element.
|
* within the list of options and when the function encounters an object with
|
||||||
* @param $choices
|
* an 'options' property inside $element['#options'].
|
||||||
* Mixed: Either an associative array of items to list as choices, or an
|
|
||||||
* object with an 'option' member that is an associative array. This
|
|
||||||
* parameter is only used internally and should not be passed.
|
|
||||||
*
|
*
|
||||||
* @return
|
* @param array $element
|
||||||
* An HTML string of options for the select form element.
|
* An associative array containing the following key-value pairs:
|
||||||
|
* - #multiple: Optional Boolean indicating if the user may select more than
|
||||||
|
* one item.
|
||||||
|
* - #options: An associative array of options to render as HTML. Each array
|
||||||
|
* value can be a string, an array, or an object with an 'option' property:
|
||||||
|
* - A string or integer key whose value is a translated string is
|
||||||
|
* interpreted as a single HTML option element. Do not use placeholders
|
||||||
|
* that sanitize data: doing so will lead to double-escaping. Note that
|
||||||
|
* the key will be visible in the HTML and could be modified by malicious
|
||||||
|
* users, so don't put sensitive information in it.
|
||||||
|
* - A translated string key whose value is an array indicates a group of
|
||||||
|
* options. The translated string is used as the label attribute for the
|
||||||
|
* optgroup. Do not use placeholders to sanitize data: doing so will lead
|
||||||
|
* to double-escaping. The array should contain the options you wish to
|
||||||
|
* group and should follow the syntax of $element['#options'].
|
||||||
|
* - If the function encounters a string or integer key whose value is an
|
||||||
|
* object with an 'option' property, the key is ignored, the contents of
|
||||||
|
* the option property are interpreted as $element['#options'], and the
|
||||||
|
* resulting HTML is added to the output.
|
||||||
|
* - #value: Optional integer, string, or array representing which option(s)
|
||||||
|
* to pre-select when the list is first displayed. The integer or string
|
||||||
|
* must match the key of an option in the '#options' list. If '#multiple' is
|
||||||
|
* TRUE, this can be an array of integers or strings.
|
||||||
|
* @param array|null $choices
|
||||||
|
* (optional) Either an associative array of options in the same format as
|
||||||
|
* $element['#options'] above, or NULL. This parameter is only used internally
|
||||||
|
* and is not intended to be passed in to the initial function call.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* An HTML string of options and optgroups for use in a select form element.
|
||||||
*/
|
*/
|
||||||
function form_select_options($element, $choices = NULL) {
|
function form_select_options($element, $choices = NULL) {
|
||||||
if (!isset($choices)) {
|
if (!isset($choices)) {
|
||||||
@ -2722,7 +2783,7 @@ function form_select_options($element, $choices = NULL) {
|
|||||||
$options = '';
|
$options = '';
|
||||||
foreach ($choices as $key => $choice) {
|
foreach ($choices as $key => $choice) {
|
||||||
if (is_array($choice)) {
|
if (is_array($choice)) {
|
||||||
$options .= '<optgroup label="' . $key . '">';
|
$options .= '<optgroup label="' . check_plain($key) . '">';
|
||||||
$options .= form_select_options($element, $choice);
|
$options .= form_select_options($element, $choice);
|
||||||
$options .= '</optgroup>';
|
$options .= '</optgroup>';
|
||||||
}
|
}
|
||||||
@ -3285,6 +3346,8 @@ function form_process_container($element, &$form_state) {
|
|||||||
*/
|
*/
|
||||||
function theme_container($variables) {
|
function theme_container($variables) {
|
||||||
$element = $variables['element'];
|
$element = $variables['element'];
|
||||||
|
// Ensure #attributes is set.
|
||||||
|
$element += array('#attributes' => array());
|
||||||
|
|
||||||
// Special handling for form elements.
|
// Special handling for form elements.
|
||||||
if (isset($element['#array_parents'])) {
|
if (isset($element['#array_parents'])) {
|
||||||
|
@ -420,7 +420,7 @@ abstract class DatabaseTasks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!empty($message)) {
|
if (!empty($message)) {
|
||||||
$message = '<p>In order for Drupal to work, and to continue with the installation process, you must resolve all issues reported below. For more help with configuring your database server, see the <a href="http://drupal.org/getting-started/install">installation handbook</a>. If you are unsure what any of this means you should probably contact your hosting provider.</p>' . $message;
|
$message = 'Resolve all issues below to continue the installation. For help configuring your database server, see the <a href="http://drupal.org/getting-started/install">installation handbook</a>, or contact your hosting provider.' . $message;
|
||||||
throw new DatabaseTaskException($message);
|
throw new DatabaseTaskException($message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -653,6 +653,13 @@ function drupal_rewrite_settings($settings = array(), $prefix = '') {
|
|||||||
if ($fp && fwrite($fp, $buffer) === FALSE) {
|
if ($fp && fwrite($fp, $buffer) === FALSE) {
|
||||||
throw new Exception(st('Failed to modify %settings. Verify the file permissions.', array('%settings' => $settings_file)));
|
throw new Exception(st('Failed to modify %settings. Verify the file permissions.', array('%settings' => $settings_file)));
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// The existing settings.php file might have been included already. In
|
||||||
|
// case an opcode cache is enabled, the rewritten contents of the file
|
||||||
|
// will not be reflected in this process. Ensure to invalidate the file
|
||||||
|
// in case an opcode cache is enabled.
|
||||||
|
drupal_clear_opcode_cache(DRUPAL_ROOT . '/' . $settings_file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new Exception(st('Failed to open %settings. Verify the file permissions.', array('%settings' => $default_settings)));
|
throw new Exception(st('Failed to open %settings. Verify the file permissions.', array('%settings' => $default_settings)));
|
||||||
|
@ -297,7 +297,7 @@ function language_negotiation_get_switch_links($type, $path) {
|
|||||||
// Add support for WCAG 2.0's Language of Parts to add language identifiers.
|
// Add support for WCAG 2.0's Language of Parts to add language identifiers.
|
||||||
// http://www.w3.org/TR/UNDERSTANDING-WCAG20/meaning-other-lang-id.html
|
// http://www.w3.org/TR/UNDERSTANDING-WCAG20/meaning-other-lang-id.html
|
||||||
foreach ($result as $langcode => $link) {
|
foreach ($result as $langcode => $link) {
|
||||||
$result[$langcode]['attributes']['lang'] = $langcode;
|
$result[$langcode]['attributes']['xml:lang'] = $langcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($result)) {
|
if (!empty($result)) {
|
||||||
|
@ -398,7 +398,7 @@ function locale_language_switcher_session($type, $path) {
|
|||||||
$links[$langcode]['query'][$param] = $langcode;
|
$links[$langcode]['query'][$param] = $langcode;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$links[$langcode]['attributes']['class'][] = ' session-active';
|
$links[$langcode]['attributes']['class'][] = 'session-active';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1931,7 +1931,7 @@ function _locale_translate_seek() {
|
|||||||
$groups[$string['group']],
|
$groups[$string['group']],
|
||||||
array('data' => check_plain(truncate_utf8($string['source'], 150, FALSE, TRUE)) . '<br /><small>' . $string['location'] . '</small>'),
|
array('data' => check_plain(truncate_utf8($string['source'], 150, FALSE, TRUE)) . '<br /><small>' . $string['location'] . '</small>'),
|
||||||
$string['context'],
|
$string['context'],
|
||||||
array('data' => _locale_translate_language_list($string['languages'], $limit_language), 'align' => 'center'),
|
array('data' => _locale_translate_language_list($string, $limit_language), 'align' => 'center'),
|
||||||
array('data' => l(t('edit'), "admin/config/regional/translate/edit/$lid", array('query' => drupal_get_destination())), 'class' => array('nowrap')),
|
array('data' => l(t('edit'), "admin/config/regional/translate/edit/$lid", array('query' => drupal_get_destination())), 'class' => array('nowrap')),
|
||||||
array('data' => l(t('delete'), "admin/config/regional/translate/delete/$lid", array('query' => drupal_get_destination())), 'class' => array('nowrap')),
|
array('data' => l(t('delete'), "admin/config/regional/translate/delete/$lid", array('query' => drupal_get_destination())), 'class' => array('nowrap')),
|
||||||
);
|
);
|
||||||
@ -2126,16 +2126,21 @@ function _locale_rebuild_js($langcode = NULL) {
|
|||||||
/**
|
/**
|
||||||
* List languages in search result table
|
* List languages in search result table
|
||||||
*/
|
*/
|
||||||
function _locale_translate_language_list($translation, $limit_language) {
|
function _locale_translate_language_list($string, $limit_language) {
|
||||||
// Add CSS.
|
// Add CSS.
|
||||||
drupal_add_css(drupal_get_path('module', 'locale') . '/locale.css');
|
drupal_add_css(drupal_get_path('module', 'locale') . '/locale.css');
|
||||||
|
|
||||||
|
// Include both translated and not yet translated target languages in the
|
||||||
|
// list. The source language is English for built-in strings and the default
|
||||||
|
// language for other strings.
|
||||||
$languages = language_list();
|
$languages = language_list();
|
||||||
unset($languages['en']);
|
$default = language_default();
|
||||||
|
$omit = $string['group'] == 'default' ? 'en' : $default->language;
|
||||||
|
unset($languages[$omit]);
|
||||||
$output = '';
|
$output = '';
|
||||||
foreach ($languages as $langcode => $language) {
|
foreach ($languages as $langcode => $language) {
|
||||||
if (!$limit_language || $limit_language == $langcode) {
|
if (!$limit_language || $limit_language == $langcode) {
|
||||||
$output .= (!empty($translation[$langcode])) ? $langcode . ' ' : "<em class=\"locale-untranslated\">$langcode</em> ";
|
$output .= (!empty($string['languages'][$langcode])) ? $langcode . ' ' : "<em class=\"locale-untranslated\">$langcode</em> ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ function _lock_id() {
|
|||||||
* Acquire (or renew) a lock, but do not block if it fails.
|
* Acquire (or renew) a lock, but do not block if it fails.
|
||||||
*
|
*
|
||||||
* @param $name
|
* @param $name
|
||||||
* The name of the lock.
|
* The name of the lock. Limit of name's length is 255 characters.
|
||||||
* @param $timeout
|
* @param $timeout
|
||||||
* A number of seconds (float) before the lock expires (minimum of 0.001).
|
* A number of seconds (float) before the lock expires (minimum of 0.001).
|
||||||
*
|
*
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* $conf['mail_line_endings'] will override this setting.
|
* $conf['mail_line_endings'] will override this setting.
|
||||||
*/
|
*/
|
||||||
define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || strpos($_SERVER['SERVER_SOFTWARE'], 'Win32') !== FALSE ? "\r\n" : "\n");
|
define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Win32') !== FALSE) ? "\r\n" : "\n");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Composes and optionally sends an e-mail message.
|
* Composes and optionally sends an e-mail message.
|
||||||
|
@ -456,7 +456,9 @@ function menu_get_item($path = NULL, $router_item = NULL) {
|
|||||||
// Rebuild if we know it's needed, or if the menu masks are missing which
|
// Rebuild if we know it's needed, or if the menu masks are missing which
|
||||||
// occurs rarely, likely due to a race condition of multiple rebuilds.
|
// occurs rarely, likely due to a race condition of multiple rebuilds.
|
||||||
if (variable_get('menu_rebuild_needed', FALSE) || !variable_get('menu_masks', array())) {
|
if (variable_get('menu_rebuild_needed', FALSE) || !variable_get('menu_masks', array())) {
|
||||||
menu_rebuild();
|
if (_menu_check_rebuild()) {
|
||||||
|
menu_rebuild();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$original_map = arg(NULL, $path);
|
$original_map = arg(NULL, $path);
|
||||||
|
|
||||||
@ -2495,6 +2497,7 @@ function menu_link_get_preferred($path = NULL, $selected_menu = NULL) {
|
|||||||
$query->addField('ml', 'weight', 'link_weight');
|
$query->addField('ml', 'weight', 'link_weight');
|
||||||
$query->fields('m');
|
$query->fields('m');
|
||||||
$query->condition('ml.link_path', $path_candidates, 'IN');
|
$query->condition('ml.link_path', $path_candidates, 'IN');
|
||||||
|
$query->addTag('preferred_menu_links');
|
||||||
|
|
||||||
// Sort candidates by link path and menu name.
|
// Sort candidates by link path and menu name.
|
||||||
$candidates = array();
|
$candidates = array();
|
||||||
@ -2692,6 +2695,21 @@ function menu_reset_static_cache() {
|
|||||||
drupal_static_reset('menu_link_get_preferred');
|
drupal_static_reset('menu_link_get_preferred');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a menu_rebuild() is necessary.
|
||||||
|
*/
|
||||||
|
function _menu_check_rebuild() {
|
||||||
|
// To absolutely ensure that the menu rebuild is required, re-load the
|
||||||
|
// variables in case they were set by another process.
|
||||||
|
$variables = variable_initialize();
|
||||||
|
if (empty($variables['menu_rebuild_needed']) && !empty($variables['menu_masks'])) {
|
||||||
|
unset($GLOBALS['conf']['menu_rebuild_needed']);
|
||||||
|
$GLOBALS['conf']['menu_masks'] = $variables['menu_masks'];
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populates the database tables used by various menu functions.
|
* Populates the database tables used by various menu functions.
|
||||||
*
|
*
|
||||||
@ -2712,6 +2730,14 @@ function menu_rebuild() {
|
|||||||
// We choose to block here since otherwise the router item may not
|
// We choose to block here since otherwise the router item may not
|
||||||
// be available in menu_execute_active_handler() resulting in a 404.
|
// be available in menu_execute_active_handler() resulting in a 404.
|
||||||
lock_wait('menu_rebuild');
|
lock_wait('menu_rebuild');
|
||||||
|
|
||||||
|
if (_menu_check_rebuild()) {
|
||||||
|
// If we get here and menu_masks was not set, then it is possible a menu
|
||||||
|
// is being reloaded, or that the process rebuilding the menu was unable
|
||||||
|
// to complete successfully. A missing menu_masks variable could result
|
||||||
|
// in a 404, so re-run the function.
|
||||||
|
return menu_rebuild();
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2736,6 +2762,12 @@ function menu_rebuild() {
|
|||||||
$transaction->rollback();
|
$transaction->rollback();
|
||||||
watchdog_exception('menu', $e);
|
watchdog_exception('menu', $e);
|
||||||
}
|
}
|
||||||
|
// Explicitly commit the transaction now; this ensures that the database
|
||||||
|
// operations during the menu rebuild are committed before the lock is made
|
||||||
|
// available again, since locks may not always reside in the same database
|
||||||
|
// connection. The lock is acquired outside of the transaction so should also
|
||||||
|
// be released outside of it.
|
||||||
|
unset($transaction);
|
||||||
|
|
||||||
lock_release('menu_rebuild');
|
lock_release('menu_rebuild');
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -265,11 +265,11 @@ function _module_build_dependencies($files) {
|
|||||||
/**
|
/**
|
||||||
* Determines whether a given module exists.
|
* Determines whether a given module exists.
|
||||||
*
|
*
|
||||||
* @param $module
|
* @param string $module
|
||||||
* The name of the module (without the .module extension).
|
* The name of the module (without the .module extension).
|
||||||
*
|
*
|
||||||
* @return
|
* @return bool
|
||||||
* TRUE if the module is both installed and enabled.
|
* TRUE if the module is both installed and enabled, FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
function module_exists($module) {
|
function module_exists($module) {
|
||||||
$list = module_list();
|
$list = module_list();
|
||||||
|
@ -140,7 +140,7 @@ function _password_enforce_log2_boundaries($count_log2) {
|
|||||||
* @param $algo
|
* @param $algo
|
||||||
* The string name of a hashing algorithm usable by hash(), like 'sha256'.
|
* The string name of a hashing algorithm usable by hash(), like 'sha256'.
|
||||||
* @param $password
|
* @param $password
|
||||||
* The plain-text password to hash.
|
* Plain-text password up to 512 bytes (128 to 512 UTF-8 characters) to hash.
|
||||||
* @param $setting
|
* @param $setting
|
||||||
* An existing hash or the output of _password_generate_salt(). Must be
|
* An existing hash or the output of _password_generate_salt(). Must be
|
||||||
* at least 12 characters (the settings and salt).
|
* at least 12 characters (the settings and salt).
|
||||||
@ -150,6 +150,10 @@ function _password_enforce_log2_boundaries($count_log2) {
|
|||||||
* The return string will be truncated at DRUPAL_HASH_LENGTH characters max.
|
* The return string will be truncated at DRUPAL_HASH_LENGTH characters max.
|
||||||
*/
|
*/
|
||||||
function _password_crypt($algo, $password, $setting) {
|
function _password_crypt($algo, $password, $setting) {
|
||||||
|
// Prevent DoS attacks by refusing to hash large passwords.
|
||||||
|
if (strlen($password) > 512) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
// The first 12 characters of an existing hash are its setting string.
|
// The first 12 characters of an existing hash are its setting string.
|
||||||
$setting = substr($setting, 0, 12);
|
$setting = substr($setting, 0, 12);
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ function _drupal_session_read($sid) {
|
|||||||
// Handle the case of first time visitors and clients that don't store
|
// Handle the case of first time visitors and clients that don't store
|
||||||
// cookies (eg. web crawlers).
|
// cookies (eg. web crawlers).
|
||||||
$insecure_session_name = substr(session_name(), 1);
|
$insecure_session_name = substr(session_name(), 1);
|
||||||
if (!isset($_COOKIE[session_name()]) && !isset($_COOKIE[$insecure_session_name])) {
|
if (empty($sid) || (!isset($_COOKIE[session_name()]) && !isset($_COOKIE[$insecure_session_name]))) {
|
||||||
$user = drupal_anonymous_user();
|
$user = drupal_anonymous_user();
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
@ -46,10 +46,9 @@ class TableSort extends SelectQueryExtender {
|
|||||||
// Based on code from db_escape_table(), but this can also contain a dot.
|
// Based on code from db_escape_table(), but this can also contain a dot.
|
||||||
$field = preg_replace('/[^A-Za-z0-9_.]+/', '', $ts['sql']);
|
$field = preg_replace('/[^A-Za-z0-9_.]+/', '', $ts['sql']);
|
||||||
|
|
||||||
// Sort order can only be ASC or DESC.
|
// orderBy() will ensure that only ASC/DESC values are accepted, so we
|
||||||
$sort = drupal_strtoupper($ts['sort']);
|
// don't need to sanitize that here.
|
||||||
$sort = in_array($sort, array('ASC', 'DESC')) ? $sort : '';
|
$this->orderBy($field, $ts['sort']);
|
||||||
$this->orderBy($field, $sort);
|
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -1029,6 +1029,7 @@ function theme($hook, $variables = array()) {
|
|||||||
}
|
}
|
||||||
$hook = $candidate;
|
$hook = $candidate;
|
||||||
}
|
}
|
||||||
|
$theme_hook_original = $hook;
|
||||||
|
|
||||||
// If there's no implementation, check for more generic fallbacks. If there's
|
// If there's no implementation, check for more generic fallbacks. If there's
|
||||||
// still no implementation, log an error and return an empty string.
|
// still no implementation, log an error and return an empty string.
|
||||||
@ -1090,6 +1091,8 @@ function theme($hook, $variables = array()) {
|
|||||||
$variables += array($info['render element'] => array());
|
$variables += array($info['render element'] => array());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$variables['theme_hook_original'] = $theme_hook_original;
|
||||||
|
|
||||||
// Invoke the variable processors, if any. The processors may specify
|
// Invoke the variable processors, if any. The processors may specify
|
||||||
// alternate suggestions for which hook's template/function to use. If the
|
// alternate suggestions for which hook's template/function to use. If the
|
||||||
// hook is a suggestion of a base hook, invoke the variable processors of
|
// hook is a suggestion of a base hook, invoke the variable processors of
|
||||||
@ -1198,7 +1201,12 @@ function theme($hook, $variables = array()) {
|
|||||||
if (isset($info['path'])) {
|
if (isset($info['path'])) {
|
||||||
$template_file = $info['path'] . '/' . $template_file;
|
$template_file = $info['path'] . '/' . $template_file;
|
||||||
}
|
}
|
||||||
$output = $render_function($template_file, $variables);
|
if (variable_get('theme_debug', FALSE)) {
|
||||||
|
$output = _theme_render_template_debug($render_function, $template_file, $variables, $extension);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$output = $render_function($template_file, $variables);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore path_to_theme()
|
// restore path_to_theme()
|
||||||
@ -1520,6 +1528,72 @@ function theme_render_template($template_file, $variables) {
|
|||||||
return ob_get_clean();
|
return ob_get_clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a template for any engine.
|
||||||
|
*
|
||||||
|
* Includes the possibility to get debug output by setting the
|
||||||
|
* theme_debug variable to TRUE.
|
||||||
|
*
|
||||||
|
* @param string $template_function
|
||||||
|
* The function to call for rendering the template.
|
||||||
|
* @param string $template_file
|
||||||
|
* The filename of the template to render.
|
||||||
|
* @param array $variables
|
||||||
|
* A keyed array of variables that will appear in the output.
|
||||||
|
* @param string $extension
|
||||||
|
* The extension used by the theme engine for template files.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The output generated by the template including debug information.
|
||||||
|
*/
|
||||||
|
function _theme_render_template_debug($template_function, $template_file, $variables, $extension) {
|
||||||
|
$output = array(
|
||||||
|
'debug_prefix' => '',
|
||||||
|
'debug_info' => '',
|
||||||
|
'rendered_markup' => call_user_func($template_function, $template_file, $variables),
|
||||||
|
'debug_suffix' => '',
|
||||||
|
);
|
||||||
|
$output['debug_prefix'] .= "\n\n<!-- THEME DEBUG -->";
|
||||||
|
$output['debug_prefix'] .= "\n<!-- CALL: theme('" . check_plain($variables['theme_hook_original']) . "') -->";
|
||||||
|
// If there are theme suggestions, reverse the array so more specific
|
||||||
|
// suggestions are shown first.
|
||||||
|
if (!empty($variables['theme_hook_suggestions'])) {
|
||||||
|
$variables['theme_hook_suggestions'] = array_reverse($variables['theme_hook_suggestions']);
|
||||||
|
}
|
||||||
|
// Add debug output for directly called suggestions like
|
||||||
|
// '#theme' => 'comment__node__article'.
|
||||||
|
if (strpos($variables['theme_hook_original'], '__') !== FALSE) {
|
||||||
|
$derived_suggestions[] = $hook = $variables['theme_hook_original'];
|
||||||
|
while ($pos = strrpos($hook, '__')) {
|
||||||
|
$hook = substr($hook, 0, $pos);
|
||||||
|
$derived_suggestions[] = $hook;
|
||||||
|
}
|
||||||
|
// Get the value of the base hook (last derived suggestion) and append it
|
||||||
|
// to the end of all theme suggestions.
|
||||||
|
$base_hook = array_pop($derived_suggestions);
|
||||||
|
$variables['theme_hook_suggestions'] = array_merge($derived_suggestions, $variables['theme_hook_suggestions']);
|
||||||
|
$variables['theme_hook_suggestions'][] = $base_hook;
|
||||||
|
}
|
||||||
|
if (!empty($variables['theme_hook_suggestions'])) {
|
||||||
|
$current_template = basename($template_file);
|
||||||
|
$suggestions = $variables['theme_hook_suggestions'];
|
||||||
|
// Only add the original theme hook if it wasn't a directly called
|
||||||
|
// suggestion.
|
||||||
|
if (strpos($variables['theme_hook_original'], '__') === FALSE) {
|
||||||
|
$suggestions[] = $variables['theme_hook_original'];
|
||||||
|
}
|
||||||
|
foreach ($suggestions as &$suggestion) {
|
||||||
|
$template = strtr($suggestion, '_', '-') . $extension;
|
||||||
|
$prefix = ($template == $current_template) ? 'x' : '*';
|
||||||
|
$suggestion = $prefix . ' ' . $template;
|
||||||
|
}
|
||||||
|
$output['debug_info'] .= "\n<!-- FILE NAME SUGGESTIONS:\n " . check_plain(implode("\n ", $suggestions)) . "\n-->";
|
||||||
|
}
|
||||||
|
$output['debug_info'] .= "\n<!-- BEGIN OUTPUT from '" . check_plain($template_file) . "' -->\n";
|
||||||
|
$output['debug_suffix'] .= "\n<!-- END OUTPUT from '" . check_plain($template_file) . "' -->\n\n";
|
||||||
|
return implode('', $output);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables a given list of themes.
|
* Enables a given list of themes.
|
||||||
*
|
*
|
||||||
@ -1617,7 +1691,7 @@ function theme_status_messages($variables) {
|
|||||||
$output .= " </ul>\n";
|
$output .= " </ul>\n";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$output .= $messages[0];
|
$output .= reset($messages);
|
||||||
}
|
}
|
||||||
$output .= "</div>\n";
|
$output .= "</div>\n";
|
||||||
}
|
}
|
||||||
@ -1690,8 +1764,6 @@ function theme_links($variables) {
|
|||||||
$output = '';
|
$output = '';
|
||||||
|
|
||||||
if (count($links) > 0) {
|
if (count($links) > 0) {
|
||||||
$output = '';
|
|
||||||
|
|
||||||
// Treat the heading first if it is present to prepend it to the
|
// Treat the heading first if it is present to prepend it to the
|
||||||
// list of links.
|
// list of links.
|
||||||
if (!empty($heading)) {
|
if (!empty($heading)) {
|
||||||
@ -2550,6 +2622,9 @@ function template_preprocess_page(&$variables) {
|
|||||||
if (!isset($variables['page'][$region_key])) {
|
if (!isset($variables['page'][$region_key])) {
|
||||||
$variables['page'][$region_key] = array();
|
$variables['page'][$region_key] = array();
|
||||||
}
|
}
|
||||||
|
if ($region_content = drupal_get_region_content($region_key)) {
|
||||||
|
$variables['page'][$region_key][]['#markup'] = $region_content;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up layout variable.
|
// Set up layout variable.
|
||||||
|
@ -116,11 +116,15 @@ function _unicode_check() {
|
|||||||
if (ini_get('mbstring.encoding_translation') != 0) {
|
if (ini_get('mbstring.encoding_translation') != 0) {
|
||||||
return array(UNICODE_ERROR, $t('Multibyte string input conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.encoding_translation</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
|
return array(UNICODE_ERROR, $t('Multibyte string input conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.encoding_translation</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
|
||||||
}
|
}
|
||||||
if (ini_get('mbstring.http_input') != 'pass') {
|
// mbstring.http_input and mbstring.http_output are deprecated and empty by
|
||||||
return array(UNICODE_ERROR, $t('Multibyte string input conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.http_input</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
|
// default in PHP 5.6.
|
||||||
}
|
if (version_compare(PHP_VERSION, '5.6.0') == -1) {
|
||||||
if (ini_get('mbstring.http_output') != 'pass') {
|
if (ini_get('mbstring.http_input') != 'pass') {
|
||||||
return array(UNICODE_ERROR, $t('Multibyte string output conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.http_output</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
|
return array(UNICODE_ERROR, $t('Multibyte string input conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.http_input</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
|
||||||
|
}
|
||||||
|
if (ini_get('mbstring.http_output') != 'pass') {
|
||||||
|
return array(UNICODE_ERROR, $t('Multibyte string output conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.http_output</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set appropriate configuration
|
// Set appropriate configuration
|
||||||
|
@ -178,7 +178,41 @@ function xmlrpc_message_parse($xmlrpc_message) {
|
|||||||
xml_set_element_handler($xmlrpc_message->_parser, 'xmlrpc_message_tag_open', 'xmlrpc_message_tag_close');
|
xml_set_element_handler($xmlrpc_message->_parser, 'xmlrpc_message_tag_open', 'xmlrpc_message_tag_close');
|
||||||
xml_set_character_data_handler($xmlrpc_message->_parser, 'xmlrpc_message_cdata');
|
xml_set_character_data_handler($xmlrpc_message->_parser, 'xmlrpc_message_cdata');
|
||||||
xmlrpc_message_set($xmlrpc_message);
|
xmlrpc_message_set($xmlrpc_message);
|
||||||
if (!xml_parse($xmlrpc_message->_parser, $xmlrpc_message->message)) {
|
|
||||||
|
// Strip XML declaration.
|
||||||
|
$header = preg_replace('/<\?xml.*?\?'.'>/s', '', substr($xmlrpc_message->message, 0, 100), 1);
|
||||||
|
$xml = trim(substr_replace($xmlrpc_message->message, $header, 0, 100));
|
||||||
|
if ($xml == '') {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
// Strip DTD.
|
||||||
|
$header = preg_replace('/^<!DOCTYPE[^>]*+>/i', '', substr($xml, 0, 200), 1);
|
||||||
|
$xml = trim(substr_replace($xml, $header, 0, 200));
|
||||||
|
if ($xml == '') {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
// Confirm the XML now starts with a valid root tag. A root tag can end in [> \t\r\n]
|
||||||
|
$root_tag = substr($xml, 0, strcspn(substr($xml, 0, 20), "> \t\r\n"));
|
||||||
|
// Reject a second DTD.
|
||||||
|
if (strtoupper($root_tag) == '<!DOCTYPE') {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!in_array($root_tag, array('<methodCall', '<methodResponse', '<fault'))) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
// Skip parsing if there is an unreasonably large number of tags.
|
||||||
|
try {
|
||||||
|
$dom = new DOMDocument();
|
||||||
|
@$dom->loadXML($xml);
|
||||||
|
if ($dom->getElementsByTagName('*')->length > variable_get('xmlrpc_message_maximum_tag_count', 30000)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!xml_parse($xmlrpc_message->_parser, $xml)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
xml_parser_free($xmlrpc_message->_parser);
|
xml_parser_free($xmlrpc_message->_parser);
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
* Invokes XML-RPC methods on this server.
|
* Invokes XML-RPC methods on this server.
|
||||||
*
|
*
|
||||||
* @param array $callbacks
|
* @param array $callbacks
|
||||||
* Array of external XML-RPC method names with the callbacks they map to.
|
* Either an associative array of external XML-RPC method names as keys with
|
||||||
|
* the callbacks they map to as values, or a more complex structure
|
||||||
|
* describing XML-RPC callbacks as returned from hook_xmlrpc().
|
||||||
*/
|
*/
|
||||||
function xmlrpc_server($callbacks) {
|
function xmlrpc_server($callbacks) {
|
||||||
$xmlrpc_server = new stdClass();
|
$xmlrpc_server = new stdClass();
|
||||||
|
22
misc/ajax.js
22
misc/ajax.js
@ -348,7 +348,7 @@ Drupal.ajax.prototype.beforeSend = function (xmlhttprequest, options) {
|
|||||||
// this is only needed for IFRAME submissions.
|
// this is only needed for IFRAME submissions.
|
||||||
var v = $.fieldValue(this.element);
|
var v = $.fieldValue(this.element);
|
||||||
if (v !== null) {
|
if (v !== null) {
|
||||||
options.extraData[this.element.name] = v;
|
options.extraData[this.element.name] = Drupal.checkPlain(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,6 +618,26 @@ Drupal.ajax.prototype.commands = {
|
|||||||
.filter(':odd').addClass('even');
|
.filter(':odd').addClass('even');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Command to add css.
|
||||||
|
*
|
||||||
|
* Uses the proprietary addImport method if available as browsers which
|
||||||
|
* support that method ignore @import statements in dynamically added
|
||||||
|
* stylesheets.
|
||||||
|
*/
|
||||||
|
add_css: function (ajax, response, status) {
|
||||||
|
// Add the styles in the normal way.
|
||||||
|
$('head').prepend(response.data);
|
||||||
|
// Add imports in the styles using the addImport method if available.
|
||||||
|
var match, importMatch = /^@import url\("(.*)"\);$/igm;
|
||||||
|
if (document.styleSheets[0].addImport && importMatch.test(response.data)) {
|
||||||
|
importMatch.lastIndex = 0;
|
||||||
|
while (match = importMatch.exec(response.data)) {
|
||||||
|
document.styleSheets[0].addImport(match[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command to update a form's build ID.
|
* Command to update a form's build ID.
|
||||||
*/
|
*/
|
||||||
|
BIN
misc/favicon.ico
BIN
misc/favicon.ico
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 5.3 KiB |
@ -500,7 +500,7 @@ Drupal.tableDrag.prototype.dragRow = function (event, self) {
|
|||||||
if (self.indentEnabled) {
|
if (self.indentEnabled) {
|
||||||
var xDiff = self.currentMouseCoords.x - self.dragObject.indentMousePos.x;
|
var xDiff = self.currentMouseCoords.x - self.dragObject.indentMousePos.x;
|
||||||
// Set the number of indentations the mouse has been moved left or right.
|
// Set the number of indentations the mouse has been moved left or right.
|
||||||
var indentDiff = Math.round(xDiff / self.indentAmount * self.rtl);
|
var indentDiff = Math.round(xDiff / self.indentAmount);
|
||||||
// Indent the row with our estimated diff, which may be further
|
// Indent the row with our estimated diff, which may be further
|
||||||
// restricted according to the rows around this row.
|
// restricted according to the rows around this row.
|
||||||
var indentChange = self.rowObject.indent(indentDiff);
|
var indentChange = self.rowObject.indent(indentDiff);
|
||||||
|
@ -57,10 +57,14 @@ Drupal.tableSelect = function () {
|
|||||||
// Keep track of the last checked checkbox.
|
// Keep track of the last checked checkbox.
|
||||||
lastChecked = e.target;
|
lastChecked = e.target;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// If all checkboxes are checked on page load, make sure the select-all one
|
||||||
|
// is checked too, otherwise keep unchecked.
|
||||||
|
updateSelectAll((checkboxes.length == $(checkboxes).filter(':checked').length));
|
||||||
};
|
};
|
||||||
|
|
||||||
Drupal.tableSelectRange = function (from, to, state) {
|
Drupal.tableSelectRange = function (from, to, state) {
|
||||||
// We determine the looping mode based on the the order of from and to.
|
// We determine the looping mode based on the order of from and to.
|
||||||
var mode = from.rowIndex > to.rowIndex ? 'previousSibling' : 'nextSibling';
|
var mode = from.rowIndex > to.rowIndex ? 'previousSibling' : 'nextSibling';
|
||||||
|
|
||||||
// Traverse through the sibling nodes.
|
// Traverse through the sibling nodes.
|
||||||
|
BIN
misc/throbber-active.gif
Normal file
BIN
misc/throbber-active.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
misc/throbber-inactive.png
Normal file
BIN
misc/throbber-inactive.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 320 B |
@ -134,6 +134,8 @@ Drupal.verticalTab.prototype = {
|
|||||||
tabShow: function () {
|
tabShow: function () {
|
||||||
// Display the tab.
|
// Display the tab.
|
||||||
this.item.show();
|
this.item.show();
|
||||||
|
// Show the vertical tabs.
|
||||||
|
this.item.closest('.vertical-tabs').show();
|
||||||
// Update .first marker for items. We need recurse from parent to retain the
|
// Update .first marker for items. We need recurse from parent to retain the
|
||||||
// actual DOM element order as jQuery implements sortOrder, but not as public
|
// actual DOM element order as jQuery implements sortOrder, but not as public
|
||||||
// method.
|
// method.
|
||||||
@ -164,6 +166,10 @@ Drupal.verticalTab.prototype = {
|
|||||||
if ($firstTab.length) {
|
if ($firstTab.length) {
|
||||||
$firstTab.data('verticalTab').focus();
|
$firstTab.data('verticalTab').focus();
|
||||||
}
|
}
|
||||||
|
// Hide the vertical tabs (if no tabs remain).
|
||||||
|
else {
|
||||||
|
this.item.closest('.vertical-tabs').hide();
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -27,7 +27,7 @@ function aggregator_aggregator_fetch($feed) {
|
|||||||
$headers['If-None-Match'] = $feed->etag;
|
$headers['If-None-Match'] = $feed->etag;
|
||||||
}
|
}
|
||||||
if ($feed->modified) {
|
if ($feed->modified) {
|
||||||
$headers['If-Modified-Since'] = gmdate(DATE_RFC1123, $feed->modified);
|
$headers['If-Modified-Since'] = gmdate(DATE_RFC7231, $feed->modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request feed.
|
// Request feed.
|
||||||
|
@ -7,8 +7,8 @@ files[] = aggregator.test
|
|||||||
configure = admin/config/services/aggregator/settings
|
configure = admin/config/services/aggregator/settings
|
||||||
stylesheets[all][] = aggregator.css
|
stylesheets[all][] = aggregator.css
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ function aggregator_test_feed($use_last_modified = FALSE, $use_etag = FALSE) {
|
|||||||
// Send appropriate response. We respond with a 304 not modified on either
|
// Send appropriate response. We respond with a 304 not modified on either
|
||||||
// etag or on last modified.
|
// etag or on last modified.
|
||||||
if ($use_last_modified) {
|
if ($use_last_modified) {
|
||||||
drupal_add_http_header('Last-Modified', gmdate(DATE_RFC1123, $last_modified));
|
drupal_add_http_header('Last-Modified', gmdate(DATE_RFC7231, $last_modified));
|
||||||
}
|
}
|
||||||
if ($use_etag) {
|
if ($use_etag) {
|
||||||
drupal_add_http_header('ETag', $etag);
|
drupal_add_http_header('ETag', $etag);
|
||||||
|
@ -272,7 +272,7 @@ function block_admin_configure($form, &$form_state, $module, $delta) {
|
|||||||
$form['settings']['title'] = array(
|
$form['settings']['title'] = array(
|
||||||
'#type' => 'textfield',
|
'#type' => 'textfield',
|
||||||
'#title' => t('Block title'),
|
'#title' => t('Block title'),
|
||||||
'#maxlength' => 64,
|
'#maxlength' => 255,
|
||||||
'#description' => $block->module == 'block' ? t('The title of the block as shown to the user.') : t('Override the default title for the block. Use <em>!placeholder</em> to display no title, or leave blank to use the default block title.', array('!placeholder' => '<none>')),
|
'#description' => $block->module == 'block' ? t('The title of the block as shown to the user.') : t('Override the default title for the block. Use <em>!placeholder</em> to display no title, or leave blank to use the default block title.', array('!placeholder' => '<none>')),
|
||||||
'#default_value' => isset($block->title) ? $block->title : '',
|
'#default_value' => isset($block->title) ? $block->title : '',
|
||||||
'#weight' => -19,
|
'#weight' => -19,
|
||||||
|
@ -6,8 +6,8 @@ core = 7.x
|
|||||||
files[] = block.test
|
files[] = block.test
|
||||||
configure = admin/structure/block
|
configure = admin/structure/block
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ function block_schema() {
|
|||||||
),
|
),
|
||||||
'title' => array(
|
'title' => array(
|
||||||
'type' => 'varchar',
|
'type' => 'varchar',
|
||||||
'length' => 64,
|
'length' => 255,
|
||||||
'not null' => TRUE,
|
'not null' => TRUE,
|
||||||
'default' => '',
|
'default' => '',
|
||||||
'description' => 'Custom title for the block. (Empty string will use block default title, <none> will remove the title, text will cause block to use specified title.)',
|
'description' => 'Custom title for the block. (Empty string will use block default title, <none> will remove the title, text will cause block to use specified title.)',
|
||||||
@ -472,6 +472,22 @@ function block_update_7008() {
|
|||||||
db_drop_field('block', 'throttle');
|
db_drop_field('block', 'throttle');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increase {block}.title length to 255 characters.
|
||||||
|
*/
|
||||||
|
function block_update_7009() {
|
||||||
|
db_change_field('block', 'title', 'title',
|
||||||
|
array(
|
||||||
|
'type' => 'varchar',
|
||||||
|
'length' => 255,
|
||||||
|
'not null' => TRUE,
|
||||||
|
'default' => '',
|
||||||
|
'description' => 'Custom title for the block. (Empty string will use block default title, <none> will remove the title, text will cause block to use specified title.)',
|
||||||
|
'translatable' => TRUE,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @} End of "addtogroup updates-7.x-extra".
|
* @} End of "addtogroup updates-7.x-extra".
|
||||||
*/
|
*/
|
||||||
|
@ -66,7 +66,7 @@ function block_help($path, $arg) {
|
|||||||
$demo_theme = !empty($arg[4]) ? $arg[4] : variable_get('theme_default', 'bartik');
|
$demo_theme = !empty($arg[4]) ? $arg[4] : variable_get('theme_default', 'bartik');
|
||||||
$themes = list_themes();
|
$themes = list_themes();
|
||||||
$output = '<p>' . t('This page provides a drag-and-drop interface for assigning a block to a region, and for controlling the order of blocks within regions. Since not all themes implement the same regions, or display regions in the same way, blocks are positioned on a per-theme basis. Remember that your changes will not be saved until you click the <em>Save blocks</em> button at the bottom of the page. Click the <em>configure</em> link next to each block to configure its specific title and visibility settings.') . '</p>';
|
$output = '<p>' . t('This page provides a drag-and-drop interface for assigning a block to a region, and for controlling the order of blocks within regions. Since not all themes implement the same regions, or display regions in the same way, blocks are positioned on a per-theme basis. Remember that your changes will not be saved until you click the <em>Save blocks</em> button at the bottom of the page. Click the <em>configure</em> link next to each block to configure its specific title and visibility settings.') . '</p>';
|
||||||
$output .= '<p>' . l(t('Demonstrate block regions (@theme)', array('@theme' => $themes[$demo_theme]->info['name'])), 'admin/structure/block/demo/' . $demo_theme) . '</p>';
|
$output .= '<p>' . l(t('Demonstrate block regions (!theme)', array('!theme' => $themes[$demo_theme]->info['name'])), 'admin/structure/block/demo/' . $demo_theme) . '</p>';
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ function block_menu() {
|
|||||||
);
|
);
|
||||||
foreach (list_themes() as $key => $theme) {
|
foreach (list_themes() as $key => $theme) {
|
||||||
$items['admin/structure/block/list/' . $key] = array(
|
$items['admin/structure/block/list/' . $key] = array(
|
||||||
'title' => check_plain($theme->info['name']),
|
'title' => $theme->info['name'],
|
||||||
'page arguments' => array($key),
|
'page arguments' => array($key),
|
||||||
'type' => $key == $default_theme ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
|
'type' => $key == $default_theme ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
|
||||||
'weight' => $key == $default_theme ? -10 : 0,
|
'weight' => $key == $default_theme ? -10 : 0,
|
||||||
@ -162,7 +162,7 @@ function block_menu() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
$items['admin/structure/block/demo/' . $key] = array(
|
$items['admin/structure/block/demo/' . $key] = array(
|
||||||
'title' => check_plain($theme->info['name']),
|
'title' => $theme->info['name'],
|
||||||
'page callback' => 'block_admin_demo',
|
'page callback' => 'block_admin_demo',
|
||||||
'page arguments' => array($key),
|
'page arguments' => array($key),
|
||||||
'type' => MENU_CALLBACK,
|
'type' => MENU_CALLBACK,
|
||||||
@ -692,6 +692,9 @@ function block_list($region) {
|
|||||||
/**
|
/**
|
||||||
* Loads a block object from the database.
|
* Loads a block object from the database.
|
||||||
*
|
*
|
||||||
|
* This function returns the first block matching the module and delta
|
||||||
|
* parameters, so it should not be used for theme-specific functionality.
|
||||||
|
*
|
||||||
* @param $module
|
* @param $module
|
||||||
* Name of the module that implements the block to load.
|
* Name of the module that implements the block to load.
|
||||||
* @param $delta
|
* @param $delta
|
||||||
@ -848,10 +851,19 @@ function block_block_list_alter(&$blocks) {
|
|||||||
* An array of visible blocks as expected by drupal_render().
|
* An array of visible blocks as expected by drupal_render().
|
||||||
*/
|
*/
|
||||||
function _block_render_blocks($region_blocks) {
|
function _block_render_blocks($region_blocks) {
|
||||||
// Block caching is not compatible with node access modules. We also
|
$cacheable = TRUE;
|
||||||
// preserve the submission of forms in blocks, by fetching from cache only
|
|
||||||
|
// We preserve the submission of forms in blocks, by fetching from cache only
|
||||||
// if the request method is 'GET' (or 'HEAD').
|
// if the request method is 'GET' (or 'HEAD').
|
||||||
$cacheable = !count(module_implements('node_grants')) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD');
|
if ($_SERVER['REQUEST_METHOD'] != 'GET' && $_SERVER['REQUEST_METHOD'] != 'HEAD') {
|
||||||
|
$cacheable = FALSE;
|
||||||
|
}
|
||||||
|
// Block caching is not usually compatible with node access modules, so by
|
||||||
|
// default it is disabled when node access modules exist. However, it can be
|
||||||
|
// allowed by using the variable 'block_cache_bypass_node_grants'.
|
||||||
|
elseif (!variable_get('block_cache_bypass_node_grants', FALSE) && count(module_implements('node_grants'))) {
|
||||||
|
$cacheable = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
// Proceed to loop over all blocks in order to compute their respective cache
|
// Proceed to loop over all blocks in order to compute their respective cache
|
||||||
// identifiers; this allows us to do one single cache_get_multiple() call
|
// identifiers; this allows us to do one single cache_get_multiple() call
|
||||||
@ -1054,7 +1066,7 @@ function block_menu_delete($menu) {
|
|||||||
* Implements hook_form_FORM_ID_alter().
|
* Implements hook_form_FORM_ID_alter().
|
||||||
*/
|
*/
|
||||||
function block_form_system_performance_settings_alter(&$form, &$form_state) {
|
function block_form_system_performance_settings_alter(&$form, &$form_state) {
|
||||||
$disabled = count(module_implements('node_grants'));
|
$disabled = (!variable_get('block_cache_bypass_node_grants', FALSE) && count(module_implements('node_grants')));
|
||||||
$form['caching']['block_cache'] = array(
|
$form['caching']['block_cache'] = array(
|
||||||
'#type' => 'checkbox',
|
'#type' => 'checkbox',
|
||||||
'#title' => t('Cache blocks'),
|
'#title' => t('Cache blocks'),
|
||||||
|
@ -75,7 +75,7 @@ class BlockTestCase extends DrupalWebTestCase {
|
|||||||
$bid = db_query("SELECT bid FROM {block_custom} WHERE info = :info", array(':info' => $custom_block['info']))->fetchField();
|
$bid = db_query("SELECT bid FROM {block_custom} WHERE info = :info", array(':info' => $custom_block['info']))->fetchField();
|
||||||
|
|
||||||
// Check to see if the custom block was created by checking that it's in the database.
|
// Check to see if the custom block was created by checking that it's in the database.
|
||||||
$this->assertNotNull($bid, 'Custom block found in database');
|
$this->assertTrue($bid, 'Custom block found in database');
|
||||||
|
|
||||||
// Check that block_block_view() returns the correct title and content.
|
// Check that block_block_view() returns the correct title and content.
|
||||||
$data = block_block_view($bid);
|
$data = block_block_view($bid);
|
||||||
@ -305,7 +305,7 @@ class BlockTestCase extends DrupalWebTestCase {
|
|||||||
))->fetchField();
|
))->fetchField();
|
||||||
|
|
||||||
// Check to see if the block was created by checking that it's in the database.
|
// Check to see if the block was created by checking that it's in the database.
|
||||||
$this->assertNotNull($bid, 'Block found in database');
|
$this->assertTrue($bid, 'Block found in database');
|
||||||
|
|
||||||
// Check whether the block can be moved to all available regions.
|
// Check whether the block can be moved to all available regions.
|
||||||
foreach ($this->regions as $region) {
|
foreach ($this->regions as $region) {
|
||||||
|
@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ regions[footer] = Footer
|
|||||||
regions[highlighted] = Highlighted
|
regions[highlighted] = Highlighted
|
||||||
regions[help] = Help
|
regions[help] = Help
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
files[] = blog.test
|
files[] = blog.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@ files[] = book.test
|
|||||||
configure = admin/content/book/settings
|
configure = admin/content/book/settings
|
||||||
stylesheets[all][] = book.css
|
stylesheets[all][] = book.css
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
files[] = color.test
|
files[] = color.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@ files[] = comment.test
|
|||||||
configure = admin/content/comment
|
configure = admin/content/comment
|
||||||
stylesheets[all][] = comment.css
|
stylesheets[all][] = comment.css
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -993,12 +993,7 @@ function comment_build_content($comment, $node, $view_mode = 'full', $langcode =
|
|||||||
$comment->content = array();
|
$comment->content = array();
|
||||||
|
|
||||||
// Allow modules to change the view mode.
|
// Allow modules to change the view mode.
|
||||||
$context = array(
|
$view_mode = key(entity_view_mode_prepare('comment', array($comment->cid => $comment), $view_mode, $langcode));
|
||||||
'entity_type' => 'comment',
|
|
||||||
'entity' => $comment,
|
|
||||||
'langcode' => $langcode,
|
|
||||||
);
|
|
||||||
drupal_alter('entity_view_mode', $view_mode, $context);
|
|
||||||
|
|
||||||
// Build fields content.
|
// Build fields content.
|
||||||
field_attach_prepare_view('comment', array($comment->cid => $comment), $view_mode, $langcode);
|
field_attach_prepare_view('comment', array($comment->cid => $comment), $view_mode, $langcode);
|
||||||
@ -1108,17 +1103,26 @@ function comment_links($comment, $node) {
|
|||||||
* An array in the format expected by drupal_render().
|
* An array in the format expected by drupal_render().
|
||||||
*/
|
*/
|
||||||
function comment_view_multiple($comments, $node, $view_mode = 'full', $weight = 0, $langcode = NULL) {
|
function comment_view_multiple($comments, $node, $view_mode = 'full', $weight = 0, $langcode = NULL) {
|
||||||
field_attach_prepare_view('comment', $comments, $view_mode, $langcode);
|
$build = array();
|
||||||
entity_prepare_view('comment', $comments, $langcode);
|
$entities_by_view_mode = entity_view_mode_prepare('comment', $comments, $view_mode, $langcode);
|
||||||
|
foreach ($entities_by_view_mode as $entity_view_mode => $entities) {
|
||||||
|
field_attach_prepare_view('comment', $entities, $entity_view_mode, $langcode);
|
||||||
|
entity_prepare_view('comment', $entities, $langcode);
|
||||||
|
|
||||||
|
foreach ($entities as $entity) {
|
||||||
|
$build[$entity->cid] = comment_view($entity, $node, $entity_view_mode, $langcode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$build = array(
|
|
||||||
'#sorted' => TRUE,
|
|
||||||
);
|
|
||||||
foreach ($comments as $comment) {
|
foreach ($comments as $comment) {
|
||||||
$build[$comment->cid] = comment_view($comment, $node, $view_mode, $langcode);
|
|
||||||
$build[$comment->cid]['#weight'] = $weight;
|
$build[$comment->cid]['#weight'] = $weight;
|
||||||
$weight++;
|
$weight++;
|
||||||
}
|
}
|
||||||
|
// Sort here, to preserve the input order of the entities that were passed to
|
||||||
|
// this function.
|
||||||
|
uasort($build, 'element_sort');
|
||||||
|
$build['#sorted'] = TRUE;
|
||||||
|
|
||||||
return $build;
|
return $build;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2603,7 +2607,7 @@ function comment_unpublish_action($comment, $context = array()) {
|
|||||||
/**
|
/**
|
||||||
* Unpublishes a comment if it contains certain keywords.
|
* Unpublishes a comment if it contains certain keywords.
|
||||||
*
|
*
|
||||||
* @param $comment
|
* @param object $comment
|
||||||
* Comment object to modify.
|
* Comment object to modify.
|
||||||
* @param array $context
|
* @param array $context
|
||||||
* Array with components:
|
* Array with components:
|
||||||
@ -2615,10 +2619,13 @@ function comment_unpublish_action($comment, $context = array()) {
|
|||||||
* @see comment_unpublish_by_keyword_action_submit()
|
* @see comment_unpublish_by_keyword_action_submit()
|
||||||
*/
|
*/
|
||||||
function comment_unpublish_by_keyword_action($comment, $context) {
|
function comment_unpublish_by_keyword_action($comment, $context) {
|
||||||
|
$node = node_load($comment->nid);
|
||||||
|
$build = comment_view($comment, $node);
|
||||||
|
$text = drupal_render($build);
|
||||||
foreach ($context['keywords'] as $keyword) {
|
foreach ($context['keywords'] as $keyword) {
|
||||||
$text = drupal_render($comment);
|
|
||||||
if (strpos($text, $keyword) !== FALSE) {
|
if (strpos($text, $keyword) !== FALSE) {
|
||||||
$comment->status = COMMENT_NOT_PUBLISHED;
|
$comment->status = COMMENT_NOT_PUBLISHED;
|
||||||
|
comment_save($comment);
|
||||||
watchdog('action', 'Unpublished comment %subject.', array('%subject' => $comment->subject));
|
watchdog('action', 'Unpublished comment %subject.', array('%subject' => $comment->subject));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ class CommentHelperCase extends DrupalWebTestCase {
|
|||||||
function setUp() {
|
function setUp() {
|
||||||
parent::setUp('comment', 'search');
|
parent::setUp('comment', 'search');
|
||||||
// Create users and test node.
|
// Create users and test node.
|
||||||
$this->admin_user = $this->drupalCreateUser(array('administer content types', 'administer comments', 'administer blocks'));
|
$this->admin_user = $this->drupalCreateUser(array('administer content types', 'administer comments', 'administer blocks', 'administer actions'));
|
||||||
$this->web_user = $this->drupalCreateUser(array('access comments', 'post comments', 'create article content', 'edit own comments'));
|
$this->web_user = $this->drupalCreateUser(array('access comments', 'post comments', 'create article content', 'edit own comments'));
|
||||||
$this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'uid' => $this->web_user->uid));
|
$this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'uid' => $this->web_user->uid));
|
||||||
}
|
}
|
||||||
@ -1973,6 +1973,41 @@ class CommentActionsTestCase extends CommentHelperCase {
|
|||||||
$this->clearWatchdog();
|
$this->clearWatchdog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the unpublish comment by keyword action.
|
||||||
|
*/
|
||||||
|
public function testCommentUnpublishByKeyword() {
|
||||||
|
$this->drupalLogin($this->admin_user);
|
||||||
|
$callback = 'comment_unpublish_by_keyword_action';
|
||||||
|
$hash = drupal_hash_base64($callback);
|
||||||
|
$comment_text = $keywords = $this->randomName();
|
||||||
|
$edit = array(
|
||||||
|
'actions_label' => $callback,
|
||||||
|
'keywords' => $keywords,
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->drupalPost("admin/config/system/actions/configure/$hash", $edit, t('Save'));
|
||||||
|
|
||||||
|
$action = db_query("SELECT aid, type, callback, parameters, label FROM {actions} WHERE callback = :callback", array(':callback' => $callback))->fetchObject();
|
||||||
|
|
||||||
|
$this->assertTrue($action, 'The action could be loaded.');
|
||||||
|
|
||||||
|
$comment = $this->postComment($this->node, $comment_text, $this->randomName());
|
||||||
|
|
||||||
|
// Load the full comment so that status is available.
|
||||||
|
$comment = comment_load($comment->id);
|
||||||
|
|
||||||
|
$this->assertTrue($comment->status == COMMENT_PUBLISHED, 'The comment status was set to published.');
|
||||||
|
|
||||||
|
comment_unpublish_by_keyword_action($comment, array('keywords' => array($keywords)));
|
||||||
|
|
||||||
|
// We need to make sure that the comment has been saved with status
|
||||||
|
// unpublished.
|
||||||
|
$this->assertEqual(comment_load($comment->cid)->status, COMMENT_NOT_PUBLISHED, 'Comment was unpublished.');
|
||||||
|
$this->assertWatchdogMessage('Unpublished comment %subject.', array('%subject' => $comment->subject), 'Found watchdog message.');
|
||||||
|
$this->clearWatchdog();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify that a watchdog message has been entered.
|
* Verify that a watchdog message has been entered.
|
||||||
*
|
*
|
||||||
|
@ -6,8 +6,8 @@ core = 7.x
|
|||||||
files[] = contact.test
|
files[] = contact.test
|
||||||
configure = admin/structure/contact
|
configure = admin/structure/contact
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ function contact_site_form_submit($form, &$form_state) {
|
|||||||
global $user, $language;
|
global $user, $language;
|
||||||
|
|
||||||
$values = $form_state['values'];
|
$values = $form_state['values'];
|
||||||
$values['sender'] = $user;
|
$values['sender'] = clone $user;
|
||||||
$values['sender']->name = $values['name'];
|
$values['sender']->name = $values['name'];
|
||||||
$values['sender']->mail = $values['mail'];
|
$values['sender']->mail = $values['mail'];
|
||||||
$values['category'] = contact_load($values['cid']);
|
$values['category'] = contact_load($values['cid']);
|
||||||
@ -270,7 +270,7 @@ function contact_personal_form_submit($form, &$form_state) {
|
|||||||
global $user, $language;
|
global $user, $language;
|
||||||
|
|
||||||
$values = $form_state['values'];
|
$values = $form_state['values'];
|
||||||
$values['sender'] = $user;
|
$values['sender'] = clone $user;
|
||||||
$values['sender']->name = $values['name'];
|
$values['sender']->name = $values['name'];
|
||||||
$values['sender']->mail = $values['mail'];
|
$values['sender']->mail = $values['mail'];
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
files[] = contextual.test
|
files[] = contextual.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@ files[] = dashboard.test
|
|||||||
dependencies[] = block
|
dependencies[] = block
|
||||||
configure = admin/dashboard/customize
|
configure = admin/dashboard/customize
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -32,13 +32,13 @@ Drupal.behaviors.dashboard = {
|
|||||||
empty_text = Drupal.settings.dashboard.emptyRegionTextInactive;
|
empty_text = Drupal.settings.dashboard.emptyRegionTextInactive;
|
||||||
}
|
}
|
||||||
// We need a placeholder.
|
// We need a placeholder.
|
||||||
if ($('.placeholder', this).length == 0) {
|
if ($('.dashboard-placeholder', this).length == 0) {
|
||||||
$(this).append('<div class="placeholder"></div>');
|
$(this).append('<div class="dashboard-placeholder"></div>');
|
||||||
}
|
}
|
||||||
$('.placeholder', this).html(empty_text);
|
$('.dashboard-placeholder', this).html(empty_text);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$('.placeholder', this).remove();
|
$('.dashboard-placeholder', this).remove();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
files[] = dblog.test
|
files[] = dblog.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -1328,10 +1328,27 @@ function hook_field_attach_load($entity_type, $entities, $age, $options) {
|
|||||||
* @param $entity
|
* @param $entity
|
||||||
* The entity with fields to validate.
|
* The entity with fields to validate.
|
||||||
* @param array $errors
|
* @param array $errors
|
||||||
* An associative array of errors keyed by field_name, language, delta.
|
* The array of errors (keyed by field name, language code, and delta) that
|
||||||
|
* have already been reported for the entity. The function should add its
|
||||||
|
* errors to this array. Each error is an associative array with the following
|
||||||
|
* keys and values:
|
||||||
|
* - error: An error code (should be a string prefixed with the module name).
|
||||||
|
* - message: The human readable message to be displayed.
|
||||||
*/
|
*/
|
||||||
function hook_field_attach_validate($entity_type, $entity, &$errors) {
|
function hook_field_attach_validate($entity_type, $entity, &$errors) {
|
||||||
// @todo Needs function body.
|
// Make sure any images in article nodes have an alt text.
|
||||||
|
if ($entity_type == 'node' && $entity->type == 'article' && !empty($entity->field_image)) {
|
||||||
|
foreach ($entity->field_image as $langcode => $items) {
|
||||||
|
foreach ($items as $delta => $item) {
|
||||||
|
if (!empty($item['fid']) && empty($item['alt'])) {
|
||||||
|
$errors['field_image'][$langcode][$delta][] = array(
|
||||||
|
'error' => 'field_example_invalid',
|
||||||
|
'message' => t('All images in articles need to have an alternative text set.'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1880,7 +1897,7 @@ function hook_field_storage_write($entity_type, $entity, $op, $fields) {
|
|||||||
$items = (array) $entity->{$field_name}[$langcode];
|
$items = (array) $entity->{$field_name}[$langcode];
|
||||||
$delta_count = 0;
|
$delta_count = 0;
|
||||||
foreach ($items as $delta => $item) {
|
foreach ($items as $delta => $item) {
|
||||||
// We now know we have someting to insert.
|
// We now know we have something to insert.
|
||||||
$do_insert = TRUE;
|
$do_insert = TRUE;
|
||||||
$record = array(
|
$record = array(
|
||||||
'entity_type' => $entity_type,
|
'entity_type' => $entity_type,
|
||||||
|
@ -318,7 +318,7 @@ function _field_invoke_multiple($op, $entity_type, $entities, &$a = NULL, &$b =
|
|||||||
// Unless a language suggestion is provided we iterate on all the
|
// Unless a language suggestion is provided we iterate on all the
|
||||||
// available languages.
|
// available languages.
|
||||||
$available_languages = field_available_languages($entity_type, $field);
|
$available_languages = field_available_languages($entity_type, $field);
|
||||||
$language = !empty($options['language'][$id]) ? $options['language'][$id] : $options['language'];
|
$language = is_array($options['language']) && !empty($options['language'][$id]) ? $options['language'][$id] : $options['language'];
|
||||||
$languages = _field_language_suggestion($available_languages, $language, $field_name);
|
$languages = _field_language_suggestion($available_languages, $language, $field_name);
|
||||||
foreach ($languages as $langcode) {
|
foreach ($languages as $langcode) {
|
||||||
$grouped_items[$field_id][$langcode][$id] = isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : array();
|
$grouped_items[$field_id][$langcode][$id] = isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : array();
|
||||||
|
@ -60,11 +60,11 @@ function field_create_field($field) {
|
|||||||
}
|
}
|
||||||
// Field type is required.
|
// Field type is required.
|
||||||
if (empty($field['type'])) {
|
if (empty($field['type'])) {
|
||||||
throw new FieldException('Attempt to create a field with no type.');
|
throw new FieldException(format_string('Attempt to create field @field_name with no type.', array('@field_name' => $field['field_name'])));
|
||||||
}
|
}
|
||||||
// Field name cannot contain invalid characters.
|
// Field name cannot contain invalid characters.
|
||||||
if (!preg_match('/^[_a-z]+[_a-z0-9]*$/', $field['field_name'])) {
|
if (!preg_match('/^[_a-z]+[_a-z0-9]*$/', $field['field_name'])) {
|
||||||
throw new FieldException('Attempt to create a field with invalid characters. Only lowercase alphanumeric characters and underscores are allowed, and only lowercase letters and underscore are allowed as the first character');
|
throw new FieldException(format_string('Attempt to create a field @field_name with invalid characters. Only lowercase alphanumeric characters and underscores are allowed, and only lowercase letters and underscore are allowed as the first character', array('@field_name' => $field['field_name'])));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Field name cannot be longer than 32 characters. We use drupal_strlen()
|
// Field name cannot be longer than 32 characters. We use drupal_strlen()
|
||||||
@ -540,9 +540,9 @@ function field_create_instance($instance) {
|
|||||||
* // Fetch an instance info array.
|
* // Fetch an instance info array.
|
||||||
* $instance_info = field_info_instance($entity_type, $field_name, $bundle_name);
|
* $instance_info = field_info_instance($entity_type, $field_name, $bundle_name);
|
||||||
* // Change a single property in the instance definition.
|
* // Change a single property in the instance definition.
|
||||||
* $instance_info['definition']['required'] = TRUE;
|
* $instance_info['required'] = TRUE;
|
||||||
* // Write the changed definition back.
|
* // Write the changed definition back.
|
||||||
* field_update_instance($instance_info['definition']);
|
* field_update_instance($instance_info);
|
||||||
* @endcode
|
* @endcode
|
||||||
*
|
*
|
||||||
* @throws FieldException
|
* @throws FieldException
|
||||||
|
@ -11,8 +11,8 @@ dependencies[] = field_sql_storage
|
|||||||
required = TRUE
|
required = TRUE
|
||||||
stylesheets[all][] = theme/field.css
|
stylesheets[all][] = theme/field.css
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -146,7 +146,10 @@ class FieldInfo {
|
|||||||
|
|
||||||
// Save in "static" and persistent caches.
|
// Save in "static" and persistent caches.
|
||||||
$this->fieldMap = $map;
|
$this->fieldMap = $map;
|
||||||
cache_set('field_info:field_map', $map, 'cache_field');
|
if (lock_acquire('field_info:field_map')) {
|
||||||
|
cache_set('field_info:field_map', $map, 'cache_field');
|
||||||
|
lock_release('field_info:field_map');
|
||||||
|
}
|
||||||
|
|
||||||
return $map;
|
return $map;
|
||||||
}
|
}
|
||||||
@ -174,7 +177,10 @@ class FieldInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Store in persistent cache.
|
// Store in persistent cache.
|
||||||
cache_set('field_info:fields', $this->fieldsById, 'cache_field');
|
if (lock_acquire('field_info:fields')) {
|
||||||
|
cache_set('field_info:fields', $this->fieldsById, 'cache_field');
|
||||||
|
lock_release('field_info:fields');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill the name/ID map.
|
// Fill the name/ID map.
|
||||||
@ -231,7 +237,10 @@ class FieldInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Store in persistent cache.
|
// Store in persistent cache.
|
||||||
cache_set('field_info:instances', $this->bundleInstances, 'cache_field');
|
if (lock_acquire('field_info:instances')) {
|
||||||
|
cache_set('field_info:instances', $this->bundleInstances, 'cache_field');
|
||||||
|
lock_release('field_info:instances');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->loadedAllInstances = TRUE;
|
$this->loadedAllInstances = TRUE;
|
||||||
@ -419,7 +428,11 @@ class FieldInfo {
|
|||||||
foreach ($instances as $instance) {
|
foreach ($instances as $instance) {
|
||||||
$cache['fields'][] = $this->fieldsById[$instance['field_id']];
|
$cache['fields'][] = $this->fieldsById[$instance['field_id']];
|
||||||
}
|
}
|
||||||
cache_set("field_info:bundle:$entity_type:$bundle", $cache, 'cache_field');
|
|
||||||
|
if (lock_acquire("field_info:bundle:$entity_type:$bundle")) {
|
||||||
|
cache_set("field_info:bundle:$entity_type:$bundle", $cache, 'cache_field');
|
||||||
|
lock_release("field_info:bundle:$entity_type:$bundle");
|
||||||
|
}
|
||||||
|
|
||||||
return $instances;
|
return $instances;
|
||||||
}
|
}
|
||||||
@ -460,7 +473,10 @@ class FieldInfo {
|
|||||||
|
|
||||||
// Store in the 'static' and persistent caches.
|
// Store in the 'static' and persistent caches.
|
||||||
$this->bundleExtraFields[$entity_type][$bundle] = $info;
|
$this->bundleExtraFields[$entity_type][$bundle] = $info;
|
||||||
cache_set("field_info:bundle_extra:$entity_type:$bundle", $info, 'cache_field');
|
if (lock_acquire("field_info:bundle_extra:$entity_type:$bundle")) {
|
||||||
|
cache_set("field_info:bundle_extra:$entity_type:$bundle", $info, 'cache_field');
|
||||||
|
lock_release("field_info:bundle_extra:$entity_type:$bundle");
|
||||||
|
}
|
||||||
|
|
||||||
return $this->bundleExtraFields[$entity_type][$bundle];
|
return $this->bundleExtraFields[$entity_type][$bundle];
|
||||||
}
|
}
|
||||||
|
@ -223,7 +223,11 @@ function _field_info_collate_types($reset = FALSE) {
|
|||||||
}
|
}
|
||||||
drupal_alter('field_storage_info', $info['storage types']);
|
drupal_alter('field_storage_info', $info['storage types']);
|
||||||
|
|
||||||
cache_set("field_info_types:$langcode", $info, 'cache_field');
|
// Set the cache if we can acquire a lock.
|
||||||
|
if (lock_acquire("field_info_types:$langcode")) {
|
||||||
|
cache_set("field_info_types:$langcode", $info, 'cache_field');
|
||||||
|
lock_release("field_info_types:$langcode");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,6 +162,7 @@ function field_schema() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
$schema['cache_field'] = drupal_get_schema_unprocessed('system', 'cache');
|
$schema['cache_field'] = drupal_get_schema_unprocessed('system', 'cache');
|
||||||
|
$schema['cache_field']['description'] = 'Cache table for the Field module to store already built field information.';
|
||||||
|
|
||||||
return $schema;
|
return $schema;
|
||||||
}
|
}
|
||||||
|
@ -342,17 +342,6 @@ function field_cron() {
|
|||||||
field_purge_batch($limit);
|
field_purge_batch($limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements hook_modules_uninstalled().
|
|
||||||
*/
|
|
||||||
function field_modules_uninstalled($modules) {
|
|
||||||
module_load_include('inc', 'field', 'field.crud');
|
|
||||||
foreach ($modules as $module) {
|
|
||||||
// TODO D7: field_module_delete is not yet implemented
|
|
||||||
// field_module_delete($module);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements hook_system_info_alter().
|
* Implements hook_system_info_alter().
|
||||||
*
|
*
|
||||||
@ -905,6 +894,7 @@ function field_view_field($entity_type, $entity, $field_name, $display = array()
|
|||||||
'entity' => $entity,
|
'entity' => $entity,
|
||||||
'view_mode' => '_custom',
|
'view_mode' => '_custom',
|
||||||
'display' => $display,
|
'display' => $display,
|
||||||
|
'language' => $langcode,
|
||||||
);
|
);
|
||||||
drupal_alter('field_attach_view', $result, $context);
|
drupal_alter('field_attach_view', $result, $context);
|
||||||
|
|
||||||
@ -947,20 +937,30 @@ function field_get_items($entity_type, $entity, $field_name, $langcode = NULL) {
|
|||||||
*/
|
*/
|
||||||
function field_has_data($field) {
|
function field_has_data($field) {
|
||||||
$query = new EntityFieldQuery();
|
$query = new EntityFieldQuery();
|
||||||
return (bool) $query
|
$query = $query->fieldCondition($field)
|
||||||
->fieldCondition($field)
|
|
||||||
->range(0, 1)
|
->range(0, 1)
|
||||||
->count()
|
->count()
|
||||||
// Neutralize the 'entity_field_access' query tag added by
|
// Neutralize the 'entity_field_access' query tag added by
|
||||||
// field_sql_storage_field_storage_query(). The result cannot depend on the
|
// field_sql_storage_field_storage_query(). The result cannot depend on the
|
||||||
// access grants of the current user.
|
// access grants of the current user.
|
||||||
->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT')
|
->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT');
|
||||||
|
|
||||||
|
return (bool) $query
|
||||||
|
->execute() || (bool) $query
|
||||||
|
->age(FIELD_LOAD_REVISION)
|
||||||
->execute();
|
->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether the user has access to a given field.
|
* Determine whether the user has access to a given field.
|
||||||
*
|
*
|
||||||
|
* This function does not determine whether access is granted to the entity
|
||||||
|
* itself, only the specific field. Callers are responsible for ensuring that
|
||||||
|
* entity access is also respected. For example, when checking field access for
|
||||||
|
* nodes, check node_access() before checking field_access(), and when checking
|
||||||
|
* field access for entities using the Entity API contributed module,
|
||||||
|
* check entity_access() before checking field_access().
|
||||||
|
*
|
||||||
* @param $op
|
* @param $op
|
||||||
* The operation to be performed. Possible values:
|
* The operation to be performed. Possible values:
|
||||||
* - 'edit'
|
* - 'edit'
|
||||||
|
@ -7,8 +7,8 @@ dependencies[] = field
|
|||||||
files[] = field_sql_storage.test
|
files[] = field_sql_storage.test
|
||||||
required = TRUE
|
required = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -64,6 +64,49 @@ function _field_sql_storage_revision_tablename($field) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a table alias for a field data table.
|
||||||
|
*
|
||||||
|
* The table alias is unique for each unique combination of field name
|
||||||
|
* (represented by $tablename), delta_group and language_group.
|
||||||
|
*
|
||||||
|
* @param $tablename
|
||||||
|
* The name of the data table for this field.
|
||||||
|
* @param $field_key
|
||||||
|
* The numeric key of this field in this query.
|
||||||
|
* @param $query
|
||||||
|
* The EntityFieldQuery that is executed.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* A string containing the generated table alias.
|
||||||
|
*/
|
||||||
|
function _field_sql_storage_tablealias($tablename, $field_key, EntityFieldQuery $query) {
|
||||||
|
// No conditions present: use a unique alias.
|
||||||
|
if (empty($query->fieldConditions[$field_key])) {
|
||||||
|
return $tablename . $field_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the delta and language condition values and append them to the alias.
|
||||||
|
$condition = $query->fieldConditions[$field_key];
|
||||||
|
$alias = $tablename;
|
||||||
|
$has_group_conditions = FALSE;
|
||||||
|
|
||||||
|
foreach (array('delta', 'language') as $column) {
|
||||||
|
if (isset($condition[$column . '_group'])) {
|
||||||
|
$alias .= '_' . $column . '_' . $condition[$column . '_group'];
|
||||||
|
$has_group_conditions = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the alias when it has delta/language group conditions.
|
||||||
|
if ($has_group_conditions) {
|
||||||
|
return $alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a unique alias in other cases.
|
||||||
|
return $tablename . $field_key;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a column name for a field data table.
|
* Generate a column name for a field data table.
|
||||||
*
|
*
|
||||||
@ -422,7 +465,7 @@ function field_sql_storage_field_storage_write($entity_type, $entity, $op, $fiel
|
|||||||
$items = (array) $entity->{$field_name}[$langcode];
|
$items = (array) $entity->{$field_name}[$langcode];
|
||||||
$delta_count = 0;
|
$delta_count = 0;
|
||||||
foreach ($items as $delta => $item) {
|
foreach ($items as $delta => $item) {
|
||||||
// We now know we have someting to insert.
|
// We now know we have something to insert.
|
||||||
$do_insert = TRUE;
|
$do_insert = TRUE;
|
||||||
$record = array(
|
$record = array(
|
||||||
'entity_type' => $entity_type,
|
'entity_type' => $entity_type,
|
||||||
@ -504,17 +547,21 @@ function field_sql_storage_field_storage_query(EntityFieldQuery $query) {
|
|||||||
$id_key = 'revision_id';
|
$id_key = 'revision_id';
|
||||||
}
|
}
|
||||||
$table_aliases = array();
|
$table_aliases = array();
|
||||||
|
$query_tables = NULL;
|
||||||
// Add tables for the fields used.
|
// Add tables for the fields used.
|
||||||
foreach ($query->fields as $key => $field) {
|
foreach ($query->fields as $key => $field) {
|
||||||
$tablename = $tablename_function($field);
|
$tablename = $tablename_function($field);
|
||||||
// Every field needs a new table.
|
$table_alias = _field_sql_storage_tablealias($tablename, $key, $query);
|
||||||
$table_alias = $tablename . $key;
|
|
||||||
$table_aliases[$key] = $table_alias;
|
$table_aliases[$key] = $table_alias;
|
||||||
if ($key) {
|
if ($key) {
|
||||||
$select_query->join($tablename, $table_alias, "$table_alias.entity_type = $field_base_table.entity_type AND $table_alias.$id_key = $field_base_table.$id_key");
|
if (!isset($query_tables[$table_alias])) {
|
||||||
|
$select_query->join($tablename, $table_alias, "$table_alias.entity_type = $field_base_table.entity_type AND $table_alias.$id_key = $field_base_table.$id_key");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$select_query = db_select($tablename, $table_alias);
|
$select_query = db_select($tablename, $table_alias);
|
||||||
|
// Store a reference to the list of joined tables.
|
||||||
|
$query_tables =& $select_query->getTables();
|
||||||
// Allow queries internal to the Field API to opt out of the access
|
// Allow queries internal to the Field API to opt out of the access
|
||||||
// check, for situations where the query's results should not depend on
|
// check, for situations where the query's results should not depend on
|
||||||
// the access grants for the current user.
|
// the access grants for the current user.
|
||||||
|
@ -438,4 +438,149 @@ class FieldSqlStorageTestCase extends DrupalWebTestCase {
|
|||||||
$this->assertEqual($foreign_key['table'], $foreign_key_name, 'Foreign key table name preserved in the schema');
|
$this->assertEqual($foreign_key['table'], $foreign_key_name, 'Foreign key table name preserved in the schema');
|
||||||
$this->assertEqual($foreign_key['columns'][$foreign_key_column], 'id', 'Foreign key column name preserved in the schema');
|
$this->assertEqual($foreign_key['columns'][$foreign_key_column], 'id', 'Foreign key column name preserved in the schema');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test handling multiple conditions on one column of a field.
|
||||||
|
*
|
||||||
|
* Tests both the result and the complexity of the query.
|
||||||
|
*/
|
||||||
|
function testFieldSqlStorageMultipleConditionsSameColumn() {
|
||||||
|
$entity = field_test_create_stub_entity(NULL, NULL);
|
||||||
|
$entity->{$this->field_name}[LANGUAGE_NONE][0] = array('value' => 1);
|
||||||
|
field_test_entity_save($entity);
|
||||||
|
|
||||||
|
$entity = field_test_create_stub_entity(NULL, NULL);
|
||||||
|
$entity->{$this->field_name}[LANGUAGE_NONE][0] = array('value' => 2);
|
||||||
|
field_test_entity_save($entity);
|
||||||
|
|
||||||
|
$entity = field_test_create_stub_entity(NULL, NULL);
|
||||||
|
$entity->{$this->field_name}[LANGUAGE_NONE][0] = array('value' => 3);
|
||||||
|
field_test_entity_save($entity);
|
||||||
|
|
||||||
|
$query = new EntityFieldQuery();
|
||||||
|
// This tag causes field_test_query_store_global_test_query_alter() to be
|
||||||
|
// invoked so that the query can be tested.
|
||||||
|
$query->addTag('store_global_test_query');
|
||||||
|
$query->entityCondition('entity_type', 'test_entity');
|
||||||
|
$query->entityCondition('bundle', 'test_bundle');
|
||||||
|
$query->fieldCondition($this->field_name, 'value', 1, '<>', 0, LANGUAGE_NONE);
|
||||||
|
$query->fieldCondition($this->field_name, 'value', 2, '<>', 0, LANGUAGE_NONE);
|
||||||
|
$result = field_sql_storage_field_storage_query($query);
|
||||||
|
|
||||||
|
// Test the results.
|
||||||
|
$this->assertEqual(1, count($result), format_string('One result should be returned, got @count', array('@count' => count($result))));
|
||||||
|
|
||||||
|
// Test the complexity of the query.
|
||||||
|
$query = $GLOBALS['test_query'];
|
||||||
|
$this->assertNotNull($query, 'Precondition: the query should be available');
|
||||||
|
$tables = $query->getTables();
|
||||||
|
$this->assertEqual(1, count($tables), 'The query contains just one table.');
|
||||||
|
|
||||||
|
// Clean up.
|
||||||
|
unset($GLOBALS['test_query']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test handling multiple conditions on multiple columns of one field.
|
||||||
|
*
|
||||||
|
* Tests both the result and the complexity of the query.
|
||||||
|
*/
|
||||||
|
function testFieldSqlStorageMultipleConditionsDifferentColumns() {
|
||||||
|
// Create the multi-column shape field
|
||||||
|
$field_name = strtolower($this->randomName());
|
||||||
|
$field = array('field_name' => $field_name, 'type' => 'shape', 'cardinality' => 4);
|
||||||
|
$field = field_create_field($field);
|
||||||
|
$instance = array(
|
||||||
|
'field_name' => $field_name,
|
||||||
|
'entity_type' => 'test_entity',
|
||||||
|
'bundle' => 'test_bundle'
|
||||||
|
);
|
||||||
|
$instance = field_create_instance($instance);
|
||||||
|
|
||||||
|
$entity = field_test_create_stub_entity(NULL, NULL);
|
||||||
|
$entity->{$field_name}[LANGUAGE_NONE][0] = array('shape' => 'A', 'color' => 'X');
|
||||||
|
field_test_entity_save($entity);
|
||||||
|
|
||||||
|
$entity = field_test_create_stub_entity(NULL, NULL);
|
||||||
|
$entity->{$field_name}[LANGUAGE_NONE][0] = array('shape' => 'B', 'color' => 'X');
|
||||||
|
field_test_entity_save($entity);
|
||||||
|
|
||||||
|
$entity = field_test_create_stub_entity(NULL, NULL);
|
||||||
|
$entity->{$field_name}[LANGUAGE_NONE][0] = array('shape' => 'A', 'color' => 'Y');
|
||||||
|
field_test_entity_save($entity);
|
||||||
|
|
||||||
|
$query = new EntityFieldQuery();
|
||||||
|
// This tag causes field_test_query_store_global_test_query_alter() to be
|
||||||
|
// invoked so that the query can be tested.
|
||||||
|
$query->addTag('store_global_test_query');
|
||||||
|
$query->entityCondition('entity_type', 'test_entity');
|
||||||
|
$query->entityCondition('bundle', 'test_bundle');
|
||||||
|
$query->fieldCondition($field_name, 'shape', 'B', '=', 'something', LANGUAGE_NONE);
|
||||||
|
$query->fieldCondition($field_name, 'color', 'X', '=', 'something', LANGUAGE_NONE);
|
||||||
|
$result = field_sql_storage_field_storage_query($query);
|
||||||
|
|
||||||
|
// Test the results.
|
||||||
|
$this->assertEqual(1, count($result), format_string('One result should be returned, got @count', array('@count' => count($result))));
|
||||||
|
|
||||||
|
// Test the complexity of the query.
|
||||||
|
$query = $GLOBALS['test_query'];
|
||||||
|
$this->assertNotNull($query, 'Precondition: the query should be available');
|
||||||
|
$tables = $query->getTables();
|
||||||
|
$this->assertEqual(1, count($tables), 'The query contains just one table.');
|
||||||
|
|
||||||
|
// Clean up.
|
||||||
|
unset($GLOBALS['test_query']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test handling multiple conditions on multiple columns of one field for multiple languages.
|
||||||
|
*
|
||||||
|
* Tests both the result and the complexity of the query.
|
||||||
|
*/
|
||||||
|
function testFieldSqlStorageMultipleConditionsDifferentColumnsMultipleLanguages() {
|
||||||
|
field_test_entity_info_translatable('test_entity', TRUE);
|
||||||
|
|
||||||
|
// Create the multi-column shape field
|
||||||
|
$field_name = strtolower($this->randomName());
|
||||||
|
$field = array('field_name' => $field_name, 'type' => 'shape', 'cardinality' => 4, 'translatable' => TRUE);
|
||||||
|
$field = field_create_field($field);
|
||||||
|
$instance = array(
|
||||||
|
'field_name' => $field_name,
|
||||||
|
'entity_type' => 'test_entity',
|
||||||
|
'bundle' => 'test_bundle',
|
||||||
|
'settings' => array(
|
||||||
|
// Prevent warning from field_test_field_load().
|
||||||
|
'test_hook_field_load' => FALSE,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
$instance = field_create_instance($instance);
|
||||||
|
|
||||||
|
$entity = field_test_create_stub_entity(NULL, NULL);
|
||||||
|
$entity->{$field_name}[LANGUAGE_NONE][0] = array('shape' => 'A', 'color' => 'X');
|
||||||
|
$entity->{$field_name}['en'][0] = array('shape' => 'B', 'color' => 'Y');
|
||||||
|
field_test_entity_save($entity);
|
||||||
|
$entity = field_test_entity_test_load($entity->ftid);
|
||||||
|
|
||||||
|
$query = new EntityFieldQuery();
|
||||||
|
// This tag causes field_test_query_store_global_test_query_alter() to be
|
||||||
|
// invoked so that the query can be tested.
|
||||||
|
$query->addTag('store_global_test_query');
|
||||||
|
$query->entityCondition('entity_type', 'test_entity');
|
||||||
|
$query->entityCondition('bundle', 'test_bundle');
|
||||||
|
$query->fieldCondition($field_name, 'color', 'X', '=', NULL, LANGUAGE_NONE);
|
||||||
|
$query->fieldCondition($field_name, 'shape', 'B', '=', NULL, 'en');
|
||||||
|
$result = field_sql_storage_field_storage_query($query);
|
||||||
|
|
||||||
|
// Test the results.
|
||||||
|
$this->assertEqual(1, count($result), format_string('One result should be returned, got @count', array('@count' => count($result))));
|
||||||
|
|
||||||
|
// Test the complexity of the query.
|
||||||
|
$query = $GLOBALS['test_query'];
|
||||||
|
$this->assertNotNull($query, 'Precondition: the query should be available');
|
||||||
|
$tables = $query->getTables();
|
||||||
|
$this->assertEqual(2, count($tables), 'The query contains two tables.');
|
||||||
|
|
||||||
|
// Clean up.
|
||||||
|
unset($GLOBALS['test_query']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,8 @@ dependencies[] = field
|
|||||||
dependencies[] = options
|
dependencies[] = options
|
||||||
files[] = tests/list.test
|
files[] = tests/list.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ package = Testing
|
|||||||
version = VERSION
|
version = VERSION
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@ core = 7.x
|
|||||||
dependencies[] = field
|
dependencies[] = field
|
||||||
files[] = number.test
|
files[] = number.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@ core = 7.x
|
|||||||
dependencies[] = field
|
dependencies[] = field
|
||||||
files[] = options.test
|
files[] = options.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@ dependencies[] = field
|
|||||||
files[] = text.test
|
files[] = text.test
|
||||||
required = TRUE
|
required = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -12,9 +12,9 @@ Drupal.behaviors.textSummary = {
|
|||||||
|
|
||||||
$summaries.once('text-summary-wrapper').each(function(index) {
|
$summaries.once('text-summary-wrapper').each(function(index) {
|
||||||
var $summary = $(this);
|
var $summary = $(this);
|
||||||
var $summaryLabel = $summary.find('label');
|
var $summaryLabel = $summary.find('label').first();
|
||||||
var $full = $widget.find('.text-full').eq(index).closest('.form-item');
|
var $full = $widget.find('.text-full').eq(index).closest('.form-item');
|
||||||
var $fullLabel = $full.find('label');
|
var $fullLabel = $full.find('label').first();
|
||||||
|
|
||||||
// Create a placeholder label when the field cardinality is
|
// Create a placeholder label when the field cardinality is
|
||||||
// unlimited or greater than 1.
|
// unlimited or greater than 1.
|
||||||
@ -23,24 +23,28 @@ Drupal.behaviors.textSummary = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup the edit/hide summary link.
|
// Setup the edit/hide summary link.
|
||||||
var $link = $('<span class="field-edit-link">(<a class="link-edit-summary" href="#">' + Drupal.t('Hide summary') + '</a>)</span>').toggle(
|
var $link = $('<span class="field-edit-link">(<a class="link-edit-summary" href="#">' + Drupal.t('Hide summary') + '</a>)</span>');
|
||||||
function () {
|
var $a = $link.find('a');
|
||||||
|
var toggleClick = true;
|
||||||
|
$link.bind('click', function (e) {
|
||||||
|
if (toggleClick) {
|
||||||
$summary.hide();
|
$summary.hide();
|
||||||
$(this).find('a').html(Drupal.t('Edit summary')).end().appendTo($fullLabel);
|
$a.html(Drupal.t('Edit summary'));
|
||||||
return false;
|
$link.appendTo($fullLabel);
|
||||||
},
|
|
||||||
function () {
|
|
||||||
$summary.show();
|
|
||||||
$(this).find('a').html(Drupal.t('Hide summary')).end().appendTo($summaryLabel);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
).appendTo($summaryLabel);
|
else {
|
||||||
|
$summary.show();
|
||||||
|
$a.html(Drupal.t('Hide summary'));
|
||||||
|
$link.appendTo($summaryLabel);
|
||||||
|
}
|
||||||
|
toggleClick = !toggleClick;
|
||||||
|
return false;
|
||||||
|
}).appendTo($summaryLabel);
|
||||||
|
|
||||||
// If no summary is set, hide the summary field.
|
// If no summary is set, hide the summary field.
|
||||||
if ($(this).find('.text-summary').val() == '') {
|
if ($(this).find('.text-summary').val() == '') {
|
||||||
$link.click();
|
$link.click();
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -245,7 +245,7 @@ function text_field_formatter_settings_summary($field, $instance, $view_mode) {
|
|||||||
$summary = '';
|
$summary = '';
|
||||||
|
|
||||||
if (strpos($display['type'], '_trimmed') !== FALSE) {
|
if (strpos($display['type'], '_trimmed') !== FALSE) {
|
||||||
$summary = t('Trim length') . ': ' . $settings['trim_length'];
|
$summary = t('Trim length') . ': ' . check_plain($settings['trim_length']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $summary;
|
return $summary;
|
||||||
|
@ -484,6 +484,66 @@ class FieldAttachStorageTestCase extends FieldAttachTestCase {
|
|||||||
$this->assertEqual($entity->{$this->field_name}[$langcode], $values, 'Insert: missing field results in default value saved');
|
$this->assertEqual($entity->{$this->field_name}[$langcode], $values, 'Insert: missing field results in default value saved');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test field_has_data().
|
||||||
|
*/
|
||||||
|
function testFieldHasData() {
|
||||||
|
$entity_type = 'test_entity';
|
||||||
|
$langcode = LANGUAGE_NONE;
|
||||||
|
|
||||||
|
$field_name = 'field_1';
|
||||||
|
$field = array('field_name' => $field_name, 'type' => 'test_field');
|
||||||
|
$field = field_create_field($field);
|
||||||
|
|
||||||
|
$this->assertFalse(field_has_data($field), "No data should be detected.");
|
||||||
|
|
||||||
|
$instance = array(
|
||||||
|
'field_name' => $field_name,
|
||||||
|
'entity_type' => 'test_entity',
|
||||||
|
'bundle' => 'test_bundle'
|
||||||
|
);
|
||||||
|
$instance = field_create_instance($instance);
|
||||||
|
$table = _field_sql_storage_tablename($field);
|
||||||
|
$revision_table = _field_sql_storage_revision_tablename($field);
|
||||||
|
|
||||||
|
$columns = array('entity_type', 'entity_id', 'revision_id', 'delta', 'language', $field_name . '_value');
|
||||||
|
|
||||||
|
$eid = 0;
|
||||||
|
|
||||||
|
// Insert values into the field revision table.
|
||||||
|
$query = db_insert($revision_table)->fields($columns);
|
||||||
|
$query->values(array($entity_type, $eid, 0, 0, $langcode, 1));
|
||||||
|
$query->execute();
|
||||||
|
|
||||||
|
$this->assertTrue(field_has_data($field), "Revision data only should be detected.");
|
||||||
|
|
||||||
|
$field_name = 'field_2';
|
||||||
|
$field = array('field_name' => $field_name, 'type' => 'test_field');
|
||||||
|
$field = field_create_field($field);
|
||||||
|
|
||||||
|
$this->assertFalse(field_has_data($field), "No data should be detected.");
|
||||||
|
|
||||||
|
$instance = array(
|
||||||
|
'field_name' => $field_name,
|
||||||
|
'entity_type' => 'test_entity',
|
||||||
|
'bundle' => 'test_bundle'
|
||||||
|
);
|
||||||
|
$instance = field_create_instance($instance);
|
||||||
|
$table = _field_sql_storage_tablename($field);
|
||||||
|
$revision_table = _field_sql_storage_revision_tablename($field);
|
||||||
|
|
||||||
|
$columns = array('entity_type', 'entity_id', 'revision_id', 'delta', 'language', $field_name . '_value');
|
||||||
|
|
||||||
|
$eid = 1;
|
||||||
|
|
||||||
|
// Insert values into the field table.
|
||||||
|
$query = db_insert($table)->fields($columns);
|
||||||
|
$query->values(array($entity_type, $eid, 0, 0, $langcode, 1));
|
||||||
|
$query->execute();
|
||||||
|
|
||||||
|
$this->assertTrue(field_has_data($field), "Values only in field table should be detected.");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test field_attach_delete().
|
* Test field_attach_delete().
|
||||||
*/
|
*/
|
||||||
@ -2146,11 +2206,12 @@ class FieldDisplayAPITestCase extends FieldTestCase {
|
|||||||
'alter' => TRUE,
|
'alter' => TRUE,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
$output = field_view_field('test_entity', $this->entity, $this->field_name, $display);
|
$output = field_view_field('test_entity', $this->entity, $this->field_name, $display, LANGUAGE_NONE);
|
||||||
$this->drupalSetContent(drupal_render($output));
|
$this->drupalSetContent(drupal_render($output));
|
||||||
$setting = $display['settings']['test_formatter_setting_multiple'];
|
$setting = $display['settings']['test_formatter_setting_multiple'];
|
||||||
$this->assertNoText($this->label, 'Label was not displayed.');
|
$this->assertNoText($this->label, 'Label was not displayed.');
|
||||||
$this->assertText('field_test_field_attach_view_alter', 'Alter fired, display passed.');
|
$this->assertText('field_test_field_attach_view_alter', 'Alter fired, display passed.');
|
||||||
|
$this->assertText('field language is ' . LANGUAGE_NONE, 'Language is placed onto the context.');
|
||||||
$array = array();
|
$array = array();
|
||||||
foreach ($this->values as $delta => $value) {
|
foreach ($this->values as $delta => $value) {
|
||||||
$array[] = $delta . ':' . $value['value'];
|
$array[] = $delta . ':' . $value['value'];
|
||||||
|
@ -6,8 +6,8 @@ files[] = field_test.entity.inc
|
|||||||
version = VERSION
|
version = VERSION
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -220,6 +220,10 @@ function field_test_field_attach_view_alter(&$output, $context) {
|
|||||||
if (!empty($context['display']['settings']['alter'])) {
|
if (!empty($context['display']['settings']['alter'])) {
|
||||||
$output['test_field'][] = array('#markup' => 'field_test_field_attach_view_alter');
|
$output['test_field'][] = array('#markup' => 'field_test_field_attach_view_alter');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($output['test_field'])) {
|
||||||
|
$output['test_field'][] = array('#markup' => 'field language is ' . $context['language']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -267,3 +271,14 @@ function field_test_query_efq_table_prefixing_test_alter(&$query) {
|
|||||||
// exception if the EFQ does not properly prefix the base table.
|
// exception if the EFQ does not properly prefix the base table.
|
||||||
$query->join('test_entity','te2','%alias.ftid = test_entity.ftid');
|
$query->join('test_entity','te2','%alias.ftid = test_entity.ftid');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements hook_query_TAG_alter() for tag 'store_global_test_query'.
|
||||||
|
*/
|
||||||
|
function field_test_query_store_global_test_query_alter($query) {
|
||||||
|
// Save the query in a global variable so that it can be examined by tests.
|
||||||
|
// This can be used by any test which needs to check a query, but see
|
||||||
|
// FieldSqlStorageTestCase::testFieldSqlStorageMultipleConditionsSameColumn()
|
||||||
|
// for an example.
|
||||||
|
$GLOBALS['test_query'] = $query;
|
||||||
|
}
|
||||||
|
@ -134,6 +134,9 @@ function hook_field_widget_settings_form($field, $instance) {
|
|||||||
/**
|
/**
|
||||||
* Specify the form elements for a formatter's settings.
|
* Specify the form elements for a formatter's settings.
|
||||||
*
|
*
|
||||||
|
* This hook is only invoked if hook_field_formatter_settings_summary()
|
||||||
|
* returns a non-empty value.
|
||||||
|
*
|
||||||
* @param $field
|
* @param $field
|
||||||
* The field structure being configured.
|
* The field structure being configured.
|
||||||
* @param $instance
|
* @param $instance
|
||||||
|
@ -6,8 +6,8 @@ core = 7.x
|
|||||||
dependencies[] = field
|
dependencies[] = field
|
||||||
files[] = field_ui.test
|
files[] = field_ui.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ Drupal.fieldUIOverview = {
|
|||||||
var dragObject = this;
|
var dragObject = this;
|
||||||
var row = dragObject.rowObject.element;
|
var row = dragObject.rowObject.element;
|
||||||
var rowHandler = $(row).data('fieldUIRowHandler');
|
var rowHandler = $(row).data('fieldUIRowHandler');
|
||||||
if (rowHandler !== undefined) {
|
if (typeof rowHandler !== 'undefined') {
|
||||||
var regionRow = $(row).prevAll('tr.region-message').get(0);
|
var regionRow = $(row).prevAll('tr.region-message').get(0);
|
||||||
var region = regionRow.className.replace(/([^ ]+[ ]+)*region-([^ ]+)-message([ ]+[^ ]+)*/, '$2');
|
var region = regionRow.className.replace(/([^ ]+[ ]+)*region-([^ ]+)-message([ ]+[^ ]+)*/, '$2');
|
||||||
|
|
||||||
@ -319,7 +319,7 @@ Drupal.fieldUIDisplayOverview.field.prototype = {
|
|||||||
if (currentValue == 'hidden') {
|
if (currentValue == 'hidden') {
|
||||||
// Restore the formatter back to the default formatter. Pseudo-fields do
|
// Restore the formatter back to the default formatter. Pseudo-fields do
|
||||||
// not have default formatters, we just return to 'visible' for those.
|
// not have default formatters, we just return to 'visible' for those.
|
||||||
var value = (this.defaultFormatter != undefined) ? this.defaultFormatter : 'visible';
|
var value = (typeof this.defaultFormatter !== 'undefined') ? this.defaultFormatter : this.$formatSelect.find('option').val();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ function file_field_instance_settings_form($field, $instance) {
|
|||||||
'#description' => t('Separate extensions with a space or comma and do not include the leading dot.'),
|
'#description' => t('Separate extensions with a space or comma and do not include the leading dot.'),
|
||||||
'#element_validate' => array('_file_generic_settings_extensions'),
|
'#element_validate' => array('_file_generic_settings_extensions'),
|
||||||
'#weight' => 1,
|
'#weight' => 1,
|
||||||
|
'#maxlength' => 256,
|
||||||
// By making this field required, we prevent a potential security issue
|
// By making this field required, we prevent a potential security issue
|
||||||
// that would allow files of any type to be uploaded.
|
// that would allow files of any type to be uploaded.
|
||||||
'#required' => TRUE,
|
'#required' => TRUE,
|
||||||
@ -251,6 +252,12 @@ function file_field_insert($entity_type, $entity, $field, $instance, $langcode,
|
|||||||
* Checks for files that have been removed from the object.
|
* Checks for files that have been removed from the object.
|
||||||
*/
|
*/
|
||||||
function file_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
function file_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||||
|
// Check whether the field is defined on the object.
|
||||||
|
if (!isset($entity->{$field['field_name']})) {
|
||||||
|
// We cannot check for removed files if the field is not defined.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
|
list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
|
||||||
|
|
||||||
// On new revisions, all files are considered to be a new usage and no
|
// On new revisions, all files are considered to be a new usage and no
|
||||||
|
@ -6,8 +6,8 @@ core = 7.x
|
|||||||
dependencies[] = field
|
dependencies[] = field
|
||||||
files[] = tests/file.test
|
files[] = tests/file.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -357,6 +357,10 @@ function file_file_delete($file) {
|
|||||||
* support for a default value.
|
* support for a default value.
|
||||||
*/
|
*/
|
||||||
function file_managed_file_process($element, &$form_state, $form) {
|
function file_managed_file_process($element, &$form_state, $form) {
|
||||||
|
// Append the '-upload' to the #id so the field label's 'for' attribute
|
||||||
|
// corresponds with the file element.
|
||||||
|
$original_id = $element['#id'];
|
||||||
|
$element['#id'] .= '-upload';
|
||||||
$fid = isset($element['#value']['fid']) ? $element['#value']['fid'] : 0;
|
$fid = isset($element['#value']['fid']) ? $element['#value']['fid'] : 0;
|
||||||
|
|
||||||
// Set some default element properties.
|
// Set some default element properties.
|
||||||
@ -366,7 +370,7 @@ function file_managed_file_process($element, &$form_state, $form) {
|
|||||||
|
|
||||||
$ajax_settings = array(
|
$ajax_settings = array(
|
||||||
'path' => 'file/ajax/' . implode('/', $element['#array_parents']) . '/' . $form['form_build_id']['#value'],
|
'path' => 'file/ajax/' . implode('/', $element['#array_parents']) . '/' . $form['form_build_id']['#value'],
|
||||||
'wrapper' => $element['#id'] . '-ajax-wrapper',
|
'wrapper' => $original_id . '-ajax-wrapper',
|
||||||
'effect' => 'fade',
|
'effect' => 'fade',
|
||||||
'progress' => array(
|
'progress' => array(
|
||||||
'type' => $element['#progress_indicator'],
|
'type' => $element['#progress_indicator'],
|
||||||
@ -461,13 +465,13 @@ function file_managed_file_process($element, &$form_state, $form) {
|
|||||||
$element['upload']['#attached']['js'] = array(
|
$element['upload']['#attached']['js'] = array(
|
||||||
array(
|
array(
|
||||||
'type' => 'setting',
|
'type' => 'setting',
|
||||||
'data' => array('file' => array('elements' => array('#' . $element['#id'] . '-upload' => $extension_list)))
|
'data' => array('file' => array('elements' => array('#' . $element['#id'] => $extension_list)))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prefix and suffix used for Ajax replacement.
|
// Prefix and suffix used for Ajax replacement.
|
||||||
$element['#prefix'] = '<div id="' . $element['#id'] . '-ajax-wrapper">';
|
$element['#prefix'] = '<div id="' . $original_id . '-ajax-wrapper">';
|
||||||
$element['#suffix'] = '</div>';
|
$element['#suffix'] = '</div>';
|
||||||
|
|
||||||
return $element;
|
return $element;
|
||||||
@ -478,6 +482,7 @@ function file_managed_file_process($element, &$form_state, $form) {
|
|||||||
*/
|
*/
|
||||||
function file_managed_file_value(&$element, $input = FALSE, $form_state = NULL) {
|
function file_managed_file_value(&$element, $input = FALSE, $form_state = NULL) {
|
||||||
$fid = 0;
|
$fid = 0;
|
||||||
|
$force_default = FALSE;
|
||||||
|
|
||||||
// Find the current value of this field from the form state.
|
// Find the current value of this field from the form state.
|
||||||
$form_state_fid = $form_state['values'];
|
$form_state_fid = $form_state['values'];
|
||||||
@ -510,15 +515,35 @@ function file_managed_file_value(&$element, $input = FALSE, $form_state = NULL)
|
|||||||
$callback($element, $input, $form_state);
|
$callback($element, $input, $form_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Load file if the FID has changed to confirm it exists.
|
// If a FID was submitted, load the file (and check access if it's not a
|
||||||
if (isset($input['fid']) && $file = file_load($input['fid'])) {
|
// public file) to confirm it exists and that the current user has access
|
||||||
$fid = $file->fid;
|
// to it.
|
||||||
|
if (isset($input['fid']) && ($file = file_load($input['fid']))) {
|
||||||
|
// By default the public:// file scheme provided by Drupal core is the
|
||||||
|
// only one that allows files to be publicly accessible to everyone, so
|
||||||
|
// it is the only one for which the file access checks are bypassed.
|
||||||
|
// Other modules which provide publicly accessible streams of their own
|
||||||
|
// in hook_stream_wrappers() can add the corresponding scheme to the
|
||||||
|
// 'file_public_schema' variable to bypass file access checks for those
|
||||||
|
// as well. This should only be done for schemes that are completely
|
||||||
|
// publicly accessible, with no download restrictions; for security
|
||||||
|
// reasons all other schemes must go through the file_download_access()
|
||||||
|
// check.
|
||||||
|
if (in_array(file_uri_scheme($file->uri), variable_get('file_public_schema', array('public'))) || file_download_access($file->uri)) {
|
||||||
|
$fid = $file->fid;
|
||||||
|
}
|
||||||
|
// If the current user doesn't have access, don't let the file be
|
||||||
|
// changed.
|
||||||
|
else {
|
||||||
|
$force_default = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is no input, set the default value.
|
// If there is no input or if the default value was requested above, use the
|
||||||
else {
|
// default value.
|
||||||
|
if ($input === FALSE || $force_default) {
|
||||||
if ($element['#extended']) {
|
if ($element['#extended']) {
|
||||||
$default_fid = isset($element['#default_value']['fid']) ? $element['#default_value']['fid'] : 0;
|
$default_fid = isset($element['#default_value']['fid']) ? $element['#default_value']['fid'] : 0;
|
||||||
$return = isset($element['#default_value']) ? $element['#default_value'] : array('fid' => 0);
|
$return = isset($element['#default_value']) ? $element['#default_value'] : array('fid' => 0);
|
||||||
|
@ -220,6 +220,128 @@ class FileFieldTestCase extends DrupalWebTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests adding a file to a non-node entity.
|
||||||
|
*/
|
||||||
|
class FileTaxonomyTermTestCase extends DrupalWebTestCase {
|
||||||
|
protected $admin_user;
|
||||||
|
|
||||||
|
public static function getInfo() {
|
||||||
|
return array(
|
||||||
|
'name' => 'Taxonomy term file test',
|
||||||
|
'description' => 'Tests adding a file to a non-node entity.',
|
||||||
|
'group' => 'File',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUp() {
|
||||||
|
$modules[] = 'file';
|
||||||
|
$modules[] = 'taxonomy';
|
||||||
|
parent::setUp($modules);
|
||||||
|
$this->admin_user = $this->drupalCreateUser(array('access content', 'access administration pages', 'administer site configuration', 'administer taxonomy'));
|
||||||
|
$this->drupalLogin($this->admin_user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a file field and attaches it to the "Tags" taxonomy vocabulary.
|
||||||
|
*
|
||||||
|
* @param $name
|
||||||
|
* The field name of the file field to create.
|
||||||
|
* @param $uri_scheme
|
||||||
|
* The URI scheme to use for the file field (for example, "private" to
|
||||||
|
* create a field that stores private files or "public" to create a field
|
||||||
|
* that stores public files).
|
||||||
|
*/
|
||||||
|
protected function createAttachFileField($name, $uri_scheme) {
|
||||||
|
$field = array(
|
||||||
|
'field_name' => $name,
|
||||||
|
'type' => 'file',
|
||||||
|
'settings' => array(
|
||||||
|
'uri_scheme' => $uri_scheme,
|
||||||
|
),
|
||||||
|
'cardinality' => 1,
|
||||||
|
);
|
||||||
|
field_create_field($field);
|
||||||
|
// Attach an instance of it.
|
||||||
|
$instance = array(
|
||||||
|
'field_name' => $name,
|
||||||
|
'label' => 'File',
|
||||||
|
'entity_type' => 'taxonomy_term',
|
||||||
|
'bundle' => 'tags',
|
||||||
|
'required' => FALSE,
|
||||||
|
'settings' => array(),
|
||||||
|
'widget' => array(
|
||||||
|
'type' => 'file_generic',
|
||||||
|
'settings' => array(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
field_create_instance($instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that a public file can be attached to a taxonomy term.
|
||||||
|
*
|
||||||
|
* This is a regression test for https://www.drupal.org/node/2305017.
|
||||||
|
*/
|
||||||
|
public function testTermFilePublic() {
|
||||||
|
$this->_testTermFile('public');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that a private file can be attached to a taxonomy term.
|
||||||
|
*
|
||||||
|
* This is a regression test for https://www.drupal.org/node/2305017.
|
||||||
|
*/
|
||||||
|
public function testTermFilePrivate() {
|
||||||
|
$this->_testTermFile('private');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs tests for attaching a file field to a taxonomy term.
|
||||||
|
*
|
||||||
|
* @param $uri_scheme
|
||||||
|
* The URI scheme to use for the file field, either "public" or "private".
|
||||||
|
*/
|
||||||
|
protected function _testTermFile($uri_scheme) {
|
||||||
|
$field_name = strtolower($this->randomName());
|
||||||
|
$this->createAttachFileField($field_name, $uri_scheme);
|
||||||
|
// Get a file to upload.
|
||||||
|
$file = current($this->drupalGetTestFiles('text'));
|
||||||
|
// Add a filesize property to files as would be read by file_load().
|
||||||
|
$file->filesize = filesize($file->uri);
|
||||||
|
$langcode = LANGUAGE_NONE;
|
||||||
|
$edit = array(
|
||||||
|
"name" => $this->randomName(),
|
||||||
|
);
|
||||||
|
// Attach a file to the term.
|
||||||
|
$edit['files[' . $field_name . '_' . $langcode . '_0]'] = drupal_realpath($file->uri);
|
||||||
|
$this->drupalPost("admin/structure/taxonomy/tags/add", $edit, t('Save'));
|
||||||
|
// Find the term ID we just created.
|
||||||
|
$tid = db_query_range('SELECT tid FROM {taxonomy_term_data} ORDER BY tid DESC', 0, 1)->fetchField();
|
||||||
|
$terms = entity_load('taxonomy_term', array($tid));
|
||||||
|
$term = $terms[$tid];
|
||||||
|
$fid = $term->{$field_name}[LANGUAGE_NONE][0]['fid'];
|
||||||
|
// Check that the uploaded file is present on the edit form.
|
||||||
|
$this->drupalGet("taxonomy/term/$tid/edit");
|
||||||
|
$file_input_name = $field_name . '[' . LANGUAGE_NONE . '][0][fid]';
|
||||||
|
$this->assertFieldByXpath('//input[@type="hidden" and @name="' . $file_input_name . '"]', $fid, 'File is attached on edit form.');
|
||||||
|
// Edit the term and change name without changing the file.
|
||||||
|
$edit = array(
|
||||||
|
"name" => $this->randomName(),
|
||||||
|
);
|
||||||
|
$this->drupalPost("taxonomy/term/$tid/edit", $edit, t('Save'));
|
||||||
|
// Check that the uploaded file is still present on the edit form.
|
||||||
|
$this->drupalGet("taxonomy/term/$tid/edit");
|
||||||
|
$file_input_name = $field_name . '[' . LANGUAGE_NONE . '][0][fid]';
|
||||||
|
$this->assertFieldByXpath('//input[@type="hidden" and @name="' . $file_input_name . '"]', $fid, 'File is attached on edit form.');
|
||||||
|
// Load term while resetting the cache.
|
||||||
|
$terms = entity_load('taxonomy_term', array($tid), array(), TRUE);
|
||||||
|
$term = $terms[$tid];
|
||||||
|
$this->assertTrue(!empty($term->{$field_name}[LANGUAGE_NONE]), 'Term has attached files.');
|
||||||
|
$this->assertEqual($term->{$field_name}[LANGUAGE_NONE][0]['fid'], $fid, 'Same File ID is attached to the term.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the 'managed_file' element type.
|
* Tests the 'managed_file' element type.
|
||||||
*
|
*
|
||||||
@ -352,6 +474,15 @@ class FileFieldWidgetTestCase extends FileFieldTestCase {
|
|||||||
$node_file = (object) $node->{$field_name}[LANGUAGE_NONE][0];
|
$node_file = (object) $node->{$field_name}[LANGUAGE_NONE][0];
|
||||||
$this->assertFileExists($node_file, 'New file saved to disk on node creation.');
|
$this->assertFileExists($node_file, 'New file saved to disk on node creation.');
|
||||||
|
|
||||||
|
// Test that running field_attach_update() leaves the file intact.
|
||||||
|
$field = new stdClass();
|
||||||
|
$field->type = $type_name;
|
||||||
|
$field->nid = $nid;
|
||||||
|
field_attach_update('node', $field);
|
||||||
|
$node = node_load($nid);
|
||||||
|
$node_file = (object) $node->{$field_name}[LANGUAGE_NONE][0];
|
||||||
|
$this->assertFileExists($node_file, 'New file still saved to disk on field update.');
|
||||||
|
|
||||||
// Ensure the file can be downloaded.
|
// Ensure the file can be downloaded.
|
||||||
$this->drupalGet(file_create_url($node_file->uri));
|
$this->drupalGet(file_create_url($node_file->uri));
|
||||||
$this->assertResponse(200, 'Confirmed that the generated URL is correct by downloading the shipped file.');
|
$this->assertResponse(200, 'Confirmed that the generated URL is correct by downloading the shipped file.');
|
||||||
@ -755,6 +886,7 @@ class FileFieldDisplayTestCase extends FileFieldTestCase {
|
|||||||
$field_settings = array(
|
$field_settings = array(
|
||||||
'display_field' => '1',
|
'display_field' => '1',
|
||||||
'display_default' => '1',
|
'display_default' => '1',
|
||||||
|
'cardinality' => FIELD_CARDINALITY_UNLIMITED,
|
||||||
);
|
);
|
||||||
$instance_settings = array(
|
$instance_settings = array(
|
||||||
'description_field' => '1',
|
'description_field' => '1',
|
||||||
@ -795,6 +927,17 @@ class FileFieldDisplayTestCase extends FileFieldTestCase {
|
|||||||
|
|
||||||
$this->assertNoRaw($default_output, 'Field is hidden when "display" option is unchecked.');
|
$this->assertNoRaw($default_output, 'Field is hidden when "display" option is unchecked.');
|
||||||
|
|
||||||
|
// Test that fields appear as expected during the preview.
|
||||||
|
// Add a second file.
|
||||||
|
$name = 'files[' . $field_name . '_' . LANGUAGE_NONE . '_1]';
|
||||||
|
$edit[$name] = drupal_realpath($test_file->uri);
|
||||||
|
|
||||||
|
// Uncheck the display checkboxes and go to the preview.
|
||||||
|
$edit[$field_name . '[' . LANGUAGE_NONE . '][0][display]'] = FALSE;
|
||||||
|
$edit[$field_name . '[' . LANGUAGE_NONE . '][1][display]'] = FALSE;
|
||||||
|
$this->drupalPost('node/' . $nid . '/edit', $edit, t('Preview'));
|
||||||
|
$this->assertRaw($field_name . '[' . LANGUAGE_NONE . '][0][display]', 'First file appears as expected.');
|
||||||
|
$this->assertRaw($field_name . '[' . LANGUAGE_NONE . '][1][display]', 'Second file appears as expected.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1167,5 +1310,18 @@ class FilePrivateTestCase extends FileFieldTestCase {
|
|||||||
// Ensure the file cannot be downloaded.
|
// Ensure the file cannot be downloaded.
|
||||||
$this->drupalGet(file_create_url($node_file->uri));
|
$this->drupalGet(file_create_url($node_file->uri));
|
||||||
$this->assertResponse(403, 'Confirmed that access is denied for the file without view field access permission.');
|
$this->assertResponse(403, 'Confirmed that access is denied for the file without view field access permission.');
|
||||||
|
|
||||||
|
// Attempt to reuse the existing file when creating a new node, and confirm
|
||||||
|
// that access is still denied.
|
||||||
|
$edit = array();
|
||||||
|
$edit['title'] = $this->randomName(8);
|
||||||
|
$edit[$field_name . '[' . LANGUAGE_NONE . '][0][fid]'] = $node_file->fid;
|
||||||
|
$this->drupalPost('node/add/page', $edit, t('Save'));
|
||||||
|
$new_node = $this->drupalGetNodeByTitle($edit['title']);
|
||||||
|
$this->assertTrue(!empty($new_node), 'Node was created.');
|
||||||
|
$this->assertUrl('node/' . $new_node->nid);
|
||||||
|
$this->assertNoRaw($node_file->filename, 'File without view field access permission does not appear after attempting to attach it to a new node.');
|
||||||
|
$this->drupalGet(file_create_url($node_file->uri));
|
||||||
|
$this->assertResponse(403, 'Confirmed that access is denied for the file without view field access permission after attempting to attach it to a new node.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@ files[] = filter.test
|
|||||||
required = TRUE
|
required = TRUE
|
||||||
configure = admin/config/content/formats
|
configure = admin/config/content/formats
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -348,9 +348,7 @@ function filter_permission() {
|
|||||||
foreach (filter_formats() as $format) {
|
foreach (filter_formats() as $format) {
|
||||||
$permission = filter_permission_name($format);
|
$permission = filter_permission_name($format);
|
||||||
if (!empty($permission)) {
|
if (!empty($permission)) {
|
||||||
// Only link to the text format configuration page if the user who is
|
$format_name_replacement = l($format->name, 'admin/config/content/formats/' . $format->format);
|
||||||
// viewing this will have access to that page.
|
|
||||||
$format_name_replacement = user_access('administer filters') ? l($format->name, 'admin/config/content/formats/' . $format->format) : drupal_placeholder($format->name);
|
|
||||||
$perms[$permission] = array(
|
$perms[$permission] = array(
|
||||||
'title' => t("Use the !text_format text format", array('!text_format' => $format_name_replacement,)),
|
'title' => t("Use the !text_format text format", array('!text_format' => $format_name_replacement,)),
|
||||||
'description' => drupal_placeholder(t('Warning: This permission may have security implications depending on how the text format is configured.')),
|
'description' => drupal_placeholder(t('Warning: This permission may have security implications depending on how the text format is configured.')),
|
||||||
|
@ -68,7 +68,7 @@ function theme_filter_tips($variables) {
|
|||||||
foreach ($tips as $name => $tiplist) {
|
foreach ($tips as $name => $tiplist) {
|
||||||
if ($multiple) {
|
if ($multiple) {
|
||||||
$output .= '<div class="filter-type filter-' . drupal_html_class($name) . '">';
|
$output .= '<div class="filter-type filter-' . drupal_html_class($name) . '">';
|
||||||
$output .= '<h3>' . $name . '</h3>';
|
$output .= '<h3>' . check_plain($name) . '</h3>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($tiplist) > 0) {
|
if (count($tiplist) > 0) {
|
||||||
|
@ -70,6 +70,15 @@ class FilterCRUDTestCase extends DrupalWebTestCase {
|
|||||||
$this->assertFalse($db_format->status, 'Database: Disabled text format is marked as disabled.');
|
$this->assertFalse($db_format->status, 'Database: Disabled text format is marked as disabled.');
|
||||||
$formats = filter_formats();
|
$formats = filter_formats();
|
||||||
$this->assertTrue(!isset($formats[$format->format]), 'filter_formats: Disabled text format no longer exists.');
|
$this->assertTrue(!isset($formats[$format->format]), 'filter_formats: Disabled text format no longer exists.');
|
||||||
|
|
||||||
|
// Add a new format to check for Xss in format name.
|
||||||
|
$format = new stdClass();
|
||||||
|
$format->format = 'xss_format';
|
||||||
|
$format->name = '<script>alert(123)</script>';
|
||||||
|
filter_format_save($format);
|
||||||
|
user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array(filter_permission_name($format) => 1));
|
||||||
|
$this->drupalGet('filter/tips');
|
||||||
|
$this->assertNoRaw($format->name, 'Text format name contains no xss.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,8 +9,8 @@ files[] = forum.test
|
|||||||
configure = admin/structure/forum
|
configure = admin/structure/forum
|
||||||
stylesheets[all][] = forum.css
|
stylesheets[all][] = forum.css
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -263,10 +263,10 @@ function _forum_node_check_node_type($node) {
|
|||||||
* Implements hook_node_view().
|
* Implements hook_node_view().
|
||||||
*/
|
*/
|
||||||
function forum_node_view($node, $view_mode) {
|
function forum_node_view($node, $view_mode) {
|
||||||
$vid = variable_get('forum_nav_vocabulary', 0);
|
|
||||||
$vocabulary = taxonomy_vocabulary_load($vid);
|
|
||||||
if (_forum_node_check_node_type($node)) {
|
if (_forum_node_check_node_type($node)) {
|
||||||
if ($view_mode == 'full' && node_is_page($node)) {
|
if ($view_mode == 'full' && node_is_page($node)) {
|
||||||
|
$vid = variable_get('forum_nav_vocabulary', 0);
|
||||||
|
$vocabulary = taxonomy_vocabulary_load($vid);
|
||||||
// Breadcrumb navigation
|
// Breadcrumb navigation
|
||||||
$breadcrumb[] = l(t('Home'), NULL);
|
$breadcrumb[] = l(t('Home'), NULL);
|
||||||
$breadcrumb[] = l($vocabulary->name, 'forum');
|
$breadcrumb[] = l($vocabulary->name, 'forum');
|
||||||
|
@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
files[] = help.test
|
files[] = help.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@ dependencies[] = file
|
|||||||
files[] = image.test
|
files[] = image.test
|
||||||
configure = admin/config/media/image-styles
|
configure = admin/config/media/image-styles
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2014-05-08
|
; Information added by Drupal.org packaging script on 2015-04-02
|
||||||
version = "7.28"
|
version = "7.36"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1399522731"
|
datestamp = "1427943826"
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user