drupal core updated to 7.28

This commit is contained in:
Bachir Soussi Chiadmi 2014-07-07 18:53:44 +02:00
parent 10de06dd70
commit c3011cef61
263 changed files with 3331 additions and 8894 deletions

View File

@ -1,4 +1,120 @@
Drupal 7.28, 2014-05-08
-----------------------
- Fixed a regression introduced in Drupal 7.27 that caused JavaScript to break
on older browsers (such as Internet Explorer 8 and earlier) when Ajax was
used.
- Increased the timeout used by the Update Manager module when it fetches data
from drupal.org (from 5 seconds to 30 seconds), to work around a problem
which causes incomplete information about security updates to be presented to
site administrators. This fix may lead to a performance slowdown on the
Update Manager administration pages, when installing Drupal distributions,
and (for sites that use the automated cron feature) on occasional page loads
by site visitors.
- Fixed the behavior of the token system's "[node:summary]" token when the body
field does not have a manual summary.
- Changed the behavior of db_query_temporary() so that it works on SELECT
queries even when they have leading comments/whitespace. A side effect of
this fix is that db_query_temporary() will now fail with an error if it is
ever used on non-SELECT queries.
- Added a "node_admin_filter" tag to the database query used to build the list
of nodes on the content administration page, to make it easier to alter.
- Made the cron queue system log any exceptions that are thrown while an item
in the queue is being processed, rather than stopping the entire PHP request.
- Improved screen reader support by adding an aria-live HTML attribute to file
upload fields when there is an error uploading the file (minor markup
change).
- Made the pager on the Tracker module listing pages show the same number of
items as other pagers throughout Drupal core (minor UI change).
- Fixed a bug which caused caches not to be properly cleared when a file entity
was saved or deleted.
- Added several missing countries to the default list returned by
country_get_list() (string change).
- Replaced the term "weight" with "influence" in the content ranking settings
for search, and added help text for administrators (string change).
- Fixed untranslatable text strings in the administrative interface for the
"Crop" effect provided by the Image module (minor string change).
- Fixed a bug in the Taxonomy module update function introduced in Drupal 7.26
that caused memory and CPU problems on sites with very large numbers of
unpublished nodes.
- Numerous small bug fixes.
- Numerous API documentation improvements.
- Additional automated test coverage.
Drupal 7.27, 2014-04-16
----------------------
- Fixed security issues (information disclosure). See SA-CORE-2014-002.
Drupal 7.26, 2014-01-15
----------------------
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2014-001.
Drupal 7.25, 2014-01-02
-----------------------
- Fixed a bug in node_save() which prevented the saved node from being updated
in hook_node_insert() and other similar hooks.
- Added a meta tag to install.php to prevent it from being indexed by search
engines even when Drupal is installed in a subfolder (minor markup change).
- Fixed a bug in the database API that caused frequent deadlock errors when
running merge queries on some servers.
- Performance improvement: Prevented block rehashing from writing blocks to the
database on every cache clear and cron run when the blocks have not changed.
This fix results in an extra 'saved' key which is added and set to TRUE for
each block returned by _block_rehash() that actually is saved to the database
(data structure change).
- Added an optional 'skip on cron' parameter to hook_cron_queue_info() to allow
queues to avoid being automatically processed on cron runs (API addition).
- Fixed a bug which caused hook_block_view_MODULE_DELTA_alter() to never be
invoked if the block delta had a hyphen in it. To implement the hook when the
block delta has a hyphen, modules should now replace hyphens with underscores
when constructing the function name for the hook implementation.
- Fixed a bug which caused cached pages to sometimes be sent to the browser
with incorrect compression. The fix adds a new 'page_compressed' key to the
$cache->data array returned by drupal_page_get_cache() (minor data structure
change).
- Fixed broken tests on PHP 5.5.
- Made the File and Image modules more robust when saving entities that have
deleted files attached. The code in file_field_presave() will now remove the
record of the deleted file from the entity before saving (minor data
structure change).
- Standardized menu callback functions throughout Drupal core to return
MENU_NOT_FOUND and MENU_ACCESS_DENIED rather than printing their own "page
not found" or "access denied" pages (minor API change in the return value of
these functions under some circumstances).
- Fixed a bug in which caches were not properly cleared when a node was deleted
via the administrative interface.
- Changed the Bartik theme to render content contained in <pre>, <code> and
similar tags in a larger font size, so it is easier to read.
- Fixed a bug in the Search module that caused exceptions to be thrown during
searches if the server was not configured to represent decimal points as a
period.
- Fixed a regression in the Image module that made image_style_url() not work
when a relative path (rather than a complete file URI) was passed to it.
- Added an optional feature to the Statistics module to allow node views to be
tracked by Ajax requests rather than during the server-side generation of the
page. This allows the node counter to work on sites that use external page
caches (string change and new administrative option:
https://drupal.org/node/2164069).
- Added a link to the drupal.org documentation page for cron to the Cron
settings page (string change).
- Added a 'drupal_anonymous_user_object' variable to allow the anonymous user
object returned by drupal_anonymous_user() to be overridden with a classed
object (API addition).
- Changed the database API to allow inserts based on a SELECT * query to work
correctly.
- Changed the database schema of the {file_managed} table to allow Drupal to
manage files larger than 4 GB.
- Changed the File module's hook_field_load() implementation to prevent file
entity properties which have the same name as file or image field properties
from overwriting the field properties (minor API change).
- Numerous small bug fixes.
- Numerous API documentation improvements.
- Additional automated test coverage.
Drupal 7.24, 2013-11-20
----------------------
- Fixed security issues (multiple vulnerabilities), see SA-CORE-2013-003.
Drupal 7.23, 2013-08-07
-----------------------
- Fixed a fatal error on PostgreSQL databases when updating the Taxonomy module

View File

@ -1,4 +1,4 @@
All Drupal code is Copyright 2001 - 2012 by the original authors.
All Drupal code is Copyright 2001 - 2013 by the original authors.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -71,12 +71,12 @@ profiles/your_site_profile/themes respectively to restrict their usage to only
sites that were installed with that specific profile.
More about installation profiles and distributions:
* Read about the difference between installation profiles and distributions:
http://drupal.org/node/1089736
* Download contributed installation profiles and distributions:
http://drupal.org/project/distributions
* Develop your own installation profile or distribution:
http://drupal.org/developing/distributions
* Read about the difference between installation profiles and distributions:
http://drupal.org/node/1089736
* Download contributed installation profiles and distributions:
http://drupal.org/project/distributions
* Develop your own installation profile or distribution:
http://drupal.org/developing/distributions
APPEARANCE
----------

View File

@ -308,10 +308,11 @@ function ajax_render($commands = array()) {
* pulls the form info from $_POST.
*
* @return
* An array containing the $form and $form_state. Use the list() function
* to break these apart:
* An array containing the $form, $form_state, $form_id, $form_build_id and an
* initial list of Ajax $commands. Use the list() function to break these
* apart:
* @code
* list($form, $form_state, $form_id, $form_build_id) = ajax_get_form();
* list($form, $form_state, $form_id, $form_build_id, $commands) = ajax_get_form();
* @endcode
*/
function ajax_get_form() {
@ -331,6 +332,17 @@ function ajax_get_form() {
drupal_exit();
}
// When a page level cache is enabled, the form-build id might have been
// replaced from within form_get_cache. If this is the case, it is also
// necessary to update it in the browser by issuing an appropriate Ajax
// command.
$commands = array();
if (isset($form['#build_id_old']) && $form['#build_id_old'] != $form['#build_id']) {
// If the form build ID has changed, issue an Ajax command to update it.
$commands[] = ajax_command_update_build_id($form);
$form_build_id = $form['#build_id'];
}
// Since some of the submit handlers are run, redirects need to be disabled.
$form_state['no_redirect'] = TRUE;
@ -345,7 +357,7 @@ function ajax_get_form() {
$form_state['input'] = $_POST;
$form_id = $form['#form_id'];
return array($form, $form_state, $form_id, $form_build_id);
return array($form, $form_state, $form_id, $form_build_id, $commands);
}
/**
@ -366,7 +378,7 @@ function ajax_get_form() {
* @see system_menu()
*/
function ajax_form_callback() {
list($form, $form_state) = ajax_get_form();
list($form, $form_state, $form_id, $form_build_id, $commands) = ajax_get_form();
drupal_process_form($form['#form_id'], $form, $form_state);
// We need to return the part of the form (or some other content) that needs
@ -379,7 +391,19 @@ function ajax_form_callback() {
$callback = $form_state['triggering_element']['#ajax']['callback'];
}
if (!empty($callback) && function_exists($callback)) {
return $callback($form, $form_state);
$result = $callback($form, $form_state);
if (!(is_array($result) && isset($result['#type']) && $result['#type'] == 'ajax')) {
// Turn the response into a #type=ajax array if it isn't one already.
$result = array(
'#type' => 'ajax',
'#commands' => ajax_prepare_response($result),
);
}
$result['#commands'] = array_merge($commands, $result['#commands']);
return $result;
}
}
@ -1210,3 +1234,26 @@ function ajax_command_restripe($selector) {
'selector' => $selector,
);
}
/**
* Creates a Drupal Ajax 'update_build_id' command.
*
* This command updates the value of a hidden form_build_id input element on a
* form. It requires the form passed in to have keys for both the old build ID
* in #build_id_old and the new build ID in #build_id.
*
* The primary use case for this Ajax command is to serve a new build ID to a
* form served from the cache to an anonymous user, preventing one anonymous
* user from accessing the form state of another anonymous users on Ajax enabled
* forms.
*
* @param $form
* The form array representing the form whose build ID should be updated.
*/
function ajax_command_update_build_id($form) {
return array(
'command' => 'updateBuildId',
'old' => $form['#build_id_old'],
'new' => $form['#build_id'],
);
}

View File

@ -8,7 +8,7 @@
/**
* The current system version.
*/
define('VERSION', '7.23');
define('VERSION', '7.28');
/**
* Core API compatibility.
@ -244,7 +244,7 @@ define('REGISTRY_WRITE_LOOKUP_CACHE', 2);
/**
* Regular expression to match PHP function names.
*
* @see http://php.net/manual/en/language.functions.php
* @see http://php.net/manual/language.functions.php
*/
define('DRUPAL_PHP_FUNCTION_PATTERN', '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*');
@ -278,7 +278,7 @@ define('DRUPAL_PHP_FUNCTION_PATTERN', '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
* error, and $var will be populated with the contents of $object['foo'], but
* that data will be passed by value, not reference. For more information on
* the PHP limitation, see the note in the official PHP documentation at·
* http://php.net/manual/en/arrayaccess.offsetget.php on
* http://php.net/manual/arrayaccess.offsetget.php on
* ArrayAccess::offsetGet().
*
* By default, the class accounts for caches where calling functions might
@ -683,7 +683,8 @@ function drupal_environment_initialize() {
ini_set('session.use_only_cookies', '1');
ini_set('session.use_trans_sid', '0');
// Don't send HTTP headers using PHP's session handler.
ini_set('session.cache_limiter', 'none');
// An empty string is used here to disable the cache limiter.
ini_set('session.cache_limiter', '');
// Use httponly session cookies.
ini_set('session.cookie_httponly', '1');
@ -1278,7 +1279,7 @@ function drupal_page_header() {
*/
function drupal_serve_page_from_cache(stdClass $cache) {
// Negotiate whether to use compression.
$page_compression = variable_get('page_compression', TRUE) && extension_loaded('zlib');
$page_compression = !empty($cache->data['page_compressed']);
$return_compressed = $page_compression && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE;
// Get headers set in hook_boot(). Keys are lower-case.
@ -1932,6 +1933,33 @@ function drupal_block_denied($ip) {
}
}
/**
* Returns a URL-safe, base64 encoded string of highly randomized bytes (over the full 8-bit range).
*
* @param $byte_count
* The number of random bytes to fetch and base64 encode.
*
* @return string
* The base64 encoded result will have a length of up to 4 * $byte_count.
*/
function drupal_random_key($byte_count = 32) {
return drupal_base64_encode(drupal_random_bytes($byte_count));
}
/**
* Returns a URL-safe, base64 encoded version of the supplied string.
*
* @param $string
* The string to convert to base64.
*
* @return string
*/
function drupal_base64_encode($string) {
$data = base64_encode($string);
// Modify the output so it's safe to use in URLs.
return strtr($data, array('+' => '-', '/' => '_', '=' => ''));
}
/**
* Returns a string of highly randomized bytes (over the full 8-bit range).
*
@ -1945,38 +1973,34 @@ function drupal_block_denied($ip) {
*/
function drupal_random_bytes($count) {
// $random_state does not use drupal_static as it stores random bytes.
static $random_state, $bytes, $php_compatible;
// Initialize on the first call. The contents of $_SERVER includes a mix of
// user-specific and system information that varies a little with each page.
if (!isset($random_state)) {
$random_state = print_r($_SERVER, TRUE);
if (function_exists('getmypid')) {
// Further initialize with the somewhat random PHP process ID.
$random_state .= getmypid();
}
$bytes = '';
}
if (strlen($bytes) < $count) {
static $random_state, $bytes, $has_openssl;
$missing_bytes = $count - strlen($bytes);
if ($missing_bytes > 0) {
// PHP versions prior 5.3.4 experienced openssl_random_pseudo_bytes()
// locking on Windows and rendered it unusable.
if (!isset($php_compatible)) {
$php_compatible = version_compare(PHP_VERSION, '5.3.4', '>=');
if (!isset($has_openssl)) {
$has_openssl = version_compare(PHP_VERSION, '5.3.4', '>=') && function_exists('openssl_random_pseudo_bytes');
}
// /dev/urandom is available on many *nix systems and is considered the
// best commonly available pseudo-random source.
if ($fh = @fopen('/dev/urandom', 'rb')) {
// openssl_random_pseudo_bytes() will find entropy in a system-dependent
// way.
if ($has_openssl) {
$bytes .= openssl_random_pseudo_bytes($missing_bytes);
}
// Else, read directly from /dev/urandom, which is available on many *nix
// systems and is considered cryptographically secure.
elseif ($fh = @fopen('/dev/urandom', 'rb')) {
// PHP only performs buffered reads, so in reality it will always read
// at least 4096 bytes. Thus, it costs nothing extra to read and store
// that much so as to speed any additional invocations.
$bytes .= fread($fh, max(4096, $count));
$bytes .= fread($fh, max(4096, $missing_bytes));
fclose($fh);
}
// openssl_random_pseudo_bytes() will find entropy in a system-dependent
// way.
elseif ($php_compatible && function_exists('openssl_random_pseudo_bytes')) {
$bytes .= openssl_random_pseudo_bytes($count - strlen($bytes));
}
// If /dev/urandom is not available or returns no bytes, this loop will
// If we couldn't get enough entropy, this simple hash-based PRNG will
// generate a good set of pseudo-random bytes on any system.
// Note that it may be important that our $random_state is passed
// through hash() prior to being rolled into $output, that the two hash()
@ -1984,9 +2008,23 @@ function drupal_random_bytes($count) {
// the microtime() - is prepended rather than appended. This is to avoid
// directly leaking $random_state via the $output stream, which could
// allow for trivial prediction of further "random" numbers.
while (strlen($bytes) < $count) {
$random_state = hash('sha256', microtime() . mt_rand() . $random_state);
$bytes .= hash('sha256', mt_rand() . $random_state, TRUE);
if (strlen($bytes) < $count) {
// Initialize on the first call. The contents of $_SERVER includes a mix of
// user-specific and system information that varies a little with each page.
if (!isset($random_state)) {
$random_state = print_r($_SERVER, TRUE);
if (function_exists('getmypid')) {
// Further initialize with the somewhat random PHP process ID.
$random_state .= getmypid();
}
$bytes = '';
}
do {
$random_state = hash('sha256', microtime() . mt_rand() . $random_state);
$bytes .= hash('sha256', mt_rand() . $random_state, TRUE);
}
while (strlen($bytes) < $count);
}
}
$output = substr($bytes, 0, $count);
@ -1997,17 +2035,21 @@ function drupal_random_bytes($count) {
/**
* Calculates a base-64 encoded, URL-safe sha-256 hmac.
*
* @param $data
* @param string $data
* String to be validated with the hmac.
* @param $key
* @param string $key
* A secret string key.
*
* @return
* @return string
* A base-64 encoded sha-256 hmac, with + replaced with -, / with _ and
* any = padding characters removed.
*/
function drupal_hmac_base64($data, $key) {
$hmac = base64_encode(hash_hmac('sha256', $data, $key, TRUE));
// Casting $data and $key to strings here is necessary to avoid empty string
// results of the hash function if they are not scalar values. As this
// function is used in security-critical contexts like token validation it is
// important that it never returns an empty string.
$hmac = base64_encode(hash_hmac('sha256', (string) $data, (string) $key, TRUE));
// Modify the hmac so it's safe to use in URLs.
return strtr($hmac, array('+' => '-', '/' => '_', '=' => ''));
}
@ -2108,7 +2150,7 @@ function drupal_array_merge_deep_array($arrays) {
* @return Object - the user object.
*/
function drupal_anonymous_user() {
$user = new stdClass();
$user = variable_get('drupal_anonymous_user_object', new stdClass);
$user->uid = 0;
$user->hostname = ip_address();
$user->roles = array();
@ -3253,8 +3295,8 @@ function registry_update() {
* However, the above line of code does not work, because PHP only allows static
* variables to be initializied by literal values, and does not allow static
* variables to be assigned to references.
* - http://php.net/manual/en/language.variables.scope.php#language.variables.scope.static
* - http://php.net/manual/en/language.variables.scope.php#language.variables.scope.references
* - http://php.net/manual/language.variables.scope.php#language.variables.scope.static
* - http://php.net/manual/language.variables.scope.php#language.variables.scope.references
* The example below shows the syntax needed to work around both limitations.
* For benchmarks and more information, see http://drupal.org/node/619666.
*

View File

@ -458,7 +458,7 @@ function drupal_get_query_array($query) {
$result = array();
if (!empty($query)) {
foreach (explode('&', $query) as $param) {
$param = explode('=', $param);
$param = explode('=', $param, 2);
$result[$param[0]] = isset($param[1]) ? rawurldecode($param[1]) : '';
}
}
@ -929,7 +929,7 @@ function drupal_http_request($url, array $options = array()) {
// If the server URL has a user then attempt to use basic authentication.
if (isset($uri['user'])) {
$options['headers']['Authorization'] = 'Basic ' . base64_encode($uri['user'] . (isset($uri['pass']) ? ':' . $uri['pass'] : ''));
$options['headers']['Authorization'] = 'Basic ' . base64_encode($uri['user'] . (isset($uri['pass']) ? ':' . $uri['pass'] : ':'));
}
// If the database prefix is being used by SimpleTest to run the tests in a copied
@ -1134,7 +1134,7 @@ function _fix_gpc_magic(&$item) {
* @param $key
* The key for the item within $_FILES.
*
* @see http://php.net/manual/en/features.file-upload.php#42280
* @see http://php.net/manual/features.file-upload.php#42280
*/
function _fix_gpc_magic_files(&$item, $key) {
if ($key != 'tmp_name') {
@ -1426,7 +1426,6 @@ function filter_xss_admin($string) {
* valid UTF-8.
*
* @see drupal_validate_utf8()
* @ingroup sanitization
*/
function filter_xss($string, $allowed_tags = array('a', 'em', 'strong', 'cite', 'blockquote', 'code', 'ul', 'ol', 'li', 'dl', 'dt', 'dd')) {
// Only operate on valid UTF-8 strings. This is necessary to prevent cross
@ -1950,7 +1949,7 @@ function format_interval($interval, $granularity = 2, $langcode = NULL) {
* get interpreted as date format characters.
* @param $timezone
* (optional) Time zone identifier, as described at
* http://php.net/manual/en/timezones.php Defaults to the time zone used to
* http://php.net/manual/timezones.php Defaults to the time zone used to
* display the page.
* @param $langcode
* (optional) Language code to translate to. Defaults to the language used to
@ -3673,17 +3672,23 @@ function drupal_load_stylesheet($file, $optimize = NULL, $reset_basepath = TRUE)
if ($basepath && !file_uri_scheme($file)) {
$file = $basepath . '/' . $file;
}
// Store the parent base path to restore it later.
$parent_base_path = $basepath;
// Set the current base path to process possible child imports.
$basepath = dirname($file);
// Load the CSS stylesheet. We suppress errors because themes may specify
// stylesheets in their .info file that don't exist in the theme's path,
// but are merely there to disable certain module CSS files.
$content = '';
if ($contents = @file_get_contents($file)) {
// Return the processed stylesheet.
return drupal_load_stylesheet_content($contents, $_optimize);
$content = drupal_load_stylesheet_content($contents, $_optimize);
}
return '';
// Restore the parent base path as the file and its childen are processed.
$basepath = $parent_base_path;
return $content;
}
/**
@ -3700,7 +3705,7 @@ function drupal_load_stylesheet($file, $optimize = NULL, $reset_basepath = TRUE)
*/
function drupal_load_stylesheet_content($contents, $optimize = FALSE) {
// Remove multiple charset declarations for standards compliance (and fixing Safari problems).
$contents = preg_replace('/^@charset\s+[\'"](\S*)\b[\'"];/i', '', $contents);
$contents = preg_replace('/^@charset\s+[\'"](\S*?)\b[\'"];/i', '', $contents);
if ($optimize) {
// Perform some safe CSS optimizations.
@ -3719,7 +3724,7 @@ function drupal_load_stylesheet_content($contents, $optimize = FALSE) {
// Remove certain whitespace.
// There are different conditions for removing leading and trailing
// whitespace.
// @see http://php.net/manual/en/regexp.reference.subpatterns.php
// @see http://php.net/manual/regexp.reference.subpatterns.php
$contents = preg_replace('<
# Strip leading and trailing whitespace.
\s*([@{};,])\s*
@ -3833,7 +3838,14 @@ function drupal_clean_css_identifier($identifier, $filter = array(' ' => '-', '_
* The cleaned class name.
*/
function drupal_html_class($class) {
return drupal_clean_css_identifier(drupal_strtolower($class));
// The output of this function will never change, so this uses a normal
// static instead of drupal_static().
static $classes = array();
if (!isset($classes[$class])) {
$classes[$class] = drupal_clean_css_identifier(drupal_strtolower($class));
}
return $classes[$class];
}
/**
@ -4097,7 +4109,7 @@ function drupal_region_class($region) {
* else being the same, JavaScript added by a call to drupal_add_js() that
* happened later in the page request gets added to the page after one for
* which drupal_add_js() happened earlier in the page request.
* - defer: If set to TRUE, the defer attribute is set on the &lt;script&gt;
* - defer: If set to TRUE, the defer attribute is set on the <script>
* tag. Defaults to FALSE.
* - cache: If set to FALSE, the JavaScript file is loaded anew on every page
* call; in other words, it is not cached. Used only when 'type' references
@ -5042,7 +5054,7 @@ function drupal_json_output($var = NULL) {
*/
function drupal_get_private_key() {
if (!($key = variable_get('drupal_private_key', 0))) {
$key = drupal_hash_base64(drupal_random_bytes(55));
$key = drupal_random_key();
variable_set('drupal_private_key', $key);
}
return $key;
@ -5054,6 +5066,11 @@ function drupal_get_private_key() {
* @param $value
* An additional value to base the token on.
*
* The generated token is based on the session ID of the current user. Normally,
* anonymous users do not have a session, so the generated token will be
* different on every page request. To generate a token for users without a
* session, manually start a session prior to calling this function.
*
* @return string
* A 43-character URL-safe token for validation, based on the user session ID,
* the hash salt provided from drupal_get_hash_salt(), and the
@ -5081,7 +5098,7 @@ function drupal_get_token($value = '') {
*/
function drupal_valid_token($token, $value = '', $skip_anonymous = FALSE) {
global $user;
return (($skip_anonymous && $user->uid == 0) || ($token == drupal_get_token($value)));
return (($skip_anonymous && $user->uid == 0) || ($token === drupal_get_token($value)));
}
function _drupal_bootstrap_full() {
@ -5114,6 +5131,10 @@ function _drupal_bootstrap_full() {
module_load_all();
// Make sure all stream wrappers are registered.
file_get_stream_wrappers();
// Ensure mt_rand is reseeded, to prevent random values from one page load
// being exploited to predict random values in subsequent page loads.
$seed = unpack("L", drupal_random_bytes(4));
mt_srand($seed[1]);
$test_info = &$GLOBALS['drupal_test_info'];
if (!empty($test_info['in_child_site'])) {
@ -5151,7 +5172,7 @@ function _drupal_bootstrap_full() {
* client without gzip support.
*
* Page compression requires the PHP zlib extension
* (http://php.net/manual/en/ref.zlib.php).
* (http://php.net/manual/ref.zlib.php).
*
* @see drupal_page_header()
*/
@ -5159,6 +5180,10 @@ function drupal_page_set_cache() {
global $base_root;
if (drupal_page_is_cacheable()) {
// Check whether the current page might be compressed.
$page_compressed = variable_get('page_compression', TRUE) && extension_loaded('zlib');
$cache = (object) array(
'cid' => $base_root . request_uri(),
'data' => array(
@ -5166,6 +5191,9 @@ function drupal_page_set_cache() {
'body' => ob_get_clean(),
'title' => drupal_get_title(),
'headers' => array(),
// We need to store whether page was compressed or not,
// because by the time it is read, the configuration might change.
'page_compressed' => $page_compressed,
),
'expire' => CACHE_TEMPORARY,
'created' => REQUEST_TIME,
@ -5183,7 +5211,7 @@ function drupal_page_set_cache() {
}
if ($cache->data['body']) {
if (variable_get('page_compression', TRUE) && extension_loaded('zlib')) {
if ($page_compressed) {
$cache->data['body'] = gzencode($cache->data['body'], 9, FORCE_GZIP);
}
cache_set($cache->cid, $cache->data, 'cache_page', $cache->expire);
@ -5258,12 +5286,23 @@ function drupal_cron_run() {
}
foreach ($queues as $queue_name => $info) {
if (!empty($info['skip on cron'])) {
// Do not run if queue wants to skip.
continue;
}
$function = $info['worker callback'];
$end = time() + (isset($info['time']) ? $info['time'] : 15);
$queue = DrupalQueue::get($queue_name);
while (time() < $end && ($item = $queue->claimItem())) {
$function($item->data);
$queue->deleteItem($item);
try {
$function($item->data);
$queue->deleteItem($item);
}
catch (Exception $e) {
// In case of exception log it and leave the item in the queue
// to be processed again later.
watchdog_exception('cron', $e);
}
}
}
// Restore the user.
@ -5918,14 +5957,16 @@ function drupal_render(&$elements) {
/**
* Renders children of an element and concatenates them.
*
* This renders all children of an element using drupal_render() and then
* joins them together into a single string.
*
* @param $element
* @param array $element
* The structured array whose children shall be rendered.
* @param $children_keys
* If the keys of the element's children are already known, they can be passed
* in to save another run of element_children().
* @param array $children_keys
* (optional) If the keys of the element's children are already known, they
* can be passed in to save another run of element_children().
*
* @return string
* The rendered HTML of all children of the element.
* @see drupal_render()
*/
function drupal_render_children(&$element, $children_keys = NULL) {
if ($children_keys === NULL) {
@ -7799,7 +7840,10 @@ function entity_load_unchanged($entity_type, $id) {
}
/**
* Get the entity controller class for an entity type.
* Gets the entity controller for an entity type.
*
* @return DrupalEntityControllerInterface
* The entity controller object for the specified entity type.
*/
function entity_get_controller($entity_type) {
$controllers = &drupal_static(__FUNCTION__, array());

View File

@ -28,18 +28,21 @@
* Most Drupal database SELECT queries are performed by a call to db_query() or
* db_query_range(). Module authors should also consider using the PagerDefault
* Extender for queries that return results that need to be presented on
* multiple pages, and the Tablesort Extender for generating appropriate queries
* for sortable tables.
* multiple pages (see https://drupal.org/node/508796), and the TableSort
* Extender for generating appropriate queries for sortable tables
* (see https://drupal.org/node/1848372).
*
* For example, one might wish to return a list of the most recent 10 nodes
* authored by a given user. Instead of directly issuing the SQL query
* @code
* SELECT n.nid, n.title, n.created FROM node n WHERE n.uid = $uid LIMIT 0, 10;
* SELECT n.nid, n.title, n.created FROM node n WHERE n.uid = $uid
* ORDER BY n.created DESC LIMIT 0, 10;
* @endcode
* one would instead call the Drupal functions:
* @code
* $result = db_query_range('SELECT n.nid, n.title, n.created
* FROM {node} n WHERE n.uid = :uid', 0, 10, array(':uid' => $uid));
* FROM {node} n WHERE n.uid = :uid
* ORDER BY n.created DESC', 0, 10, array(':uid' => $uid));
* foreach ($result as $record) {
* // Perform operations on $record->title, etc. here.
* }
@ -179,7 +182,7 @@
* concrete implementation of it to support special handling required by that
* database.
*
* @see http://php.net/manual/en/book.pdo.php
* @see http://php.net/manual/book.pdo.php
*/
abstract class DatabaseConnection extends PDO {
@ -1986,7 +1989,7 @@ interface DatabaseStatementInterface extends Traversable {
/**
* Sets the default fetch mode for this statement.
*
* See http://php.net/manual/en/pdo.constants.php for the definition of the
* See http://php.net/manual/pdo.constants.php for the definition of the
* constants used.
*
* @param $mode
@ -2005,7 +2008,7 @@ interface DatabaseStatementInterface extends Traversable {
/**
* Fetches the next row from a result set.
*
* See http://php.net/manual/en/pdo.constants.php for the definition of the
* See http://php.net/manual/pdo.constants.php for the definition of the
* constants used.
*
* @param $mode
@ -2380,14 +2383,14 @@ function db_query_range($query, $from, $count, array $args = array(), array $opt
}
/**
* Executes a query string and saves the result set to a temporary table.
* Executes a SELECT query string and saves the result set to a temporary table.
*
* The execution of the query string happens against the active database.
*
* @param $query
* The prepared statement query to run. Although it will accept both named and
* unnamed placeholders, named placeholders are strongly preferred as they are
* more self-documenting.
* The prepared SELECT statement query to run. Although it will accept both
* named and unnamed placeholders, named placeholders are strongly preferred
* as they are more self-documenting.
* @param $args
* An array of values to substitute into the query. If the query uses named
* placeholders, this is an associative array in any order. If the query uses

View File

@ -90,7 +90,7 @@ class DatabaseConnection_mysql extends DatabaseConnection {
public function queryTemporary($query, array $args = array(), array $options = array()) {
$tablename = $this->generateTemporaryTableName();
$this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE {' . $tablename . '} Engine=MEMORY SELECT', $query), $args, $options);
$this->query('CREATE TEMPORARY TABLE {' . $tablename . '} Engine=MEMORY ' . $query, $args, $options);
return $tablename;
}

View File

@ -51,7 +51,8 @@ class InsertQuery_mysql extends InsertQuery {
// If we're selecting from a SelectQuery, finish building the query and
// pass it back, as any remaining options are irrelevant.
if (!empty($this->fromQuery)) {
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') ' . $this->fromQuery;
$insert_fields_string = $insert_fields ? ' (' . implode(', ', $insert_fields) . ') ' : ' ';
return $comments . 'INSERT INTO {' . $this->table . '}' . $insert_fields_string . $this->fromQuery;
}
$query = $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';

View File

@ -146,7 +146,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
public function queryTemporary($query, array $args = array(), array $options = array()) {
$tablename = $this->generateTemporaryTableName();
$this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE {' . $tablename . '} AS SELECT', $query), $args, $options);
$this->query('CREATE TEMPORARY TABLE {' . $tablename . '} AS ' . $query, $args, $options);
return $tablename;
}

View File

@ -112,7 +112,8 @@ class InsertQuery_pgsql extends InsertQuery {
// If we're selecting from a SelectQuery, finish building the query and
// pass it back, as any remaining options are irrelevant.
if (!empty($this->fromQuery)) {
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') ' . $this->fromQuery;
$insert_fields_string = $insert_fields ? ' (' . implode(', ', $insert_fields) . ') ' : ' ';
return $comments . 'INSERT INTO {' . $this->table . '}' . $insert_fields_string . $this->fromQuery;
}
$query = $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';

View File

@ -710,10 +710,11 @@ class InsertQuery extends Query {
// first call to fields() does have an effect.
$this->fields(array_merge(array_keys($this->fromQuery->getFields()), array_keys($this->fromQuery->getExpressions())));
}
// Don't execute query without fields.
if (count($this->insertFields) + count($this->defaultFields) == 0) {
throw new NoFieldsException('There are no fields available to insert with.');
else {
// Don't execute query without fields.
if (count($this->insertFields) + count($this->defaultFields) == 0) {
throw new NoFieldsException('There are no fields available to insert with.');
}
}
// If no values have been added, silently ignore this query. This can happen
@ -1605,55 +1606,43 @@ class MergeQuery extends Query implements QueryConditionInterface {
}
public function execute() {
// Wrap multiple queries in a transaction, if the database supports it.
$transaction = $this->connection->startTransaction();
try {
if (!count($this->condition)) {
throw new InvalidMergeQueryException(t('Invalid merge query: no conditions'));
if (!count($this->condition)) {
throw new InvalidMergeQueryException(t('Invalid merge query: no conditions'));
}
$select = $this->connection->select($this->conditionTable)
->condition($this->condition);
$select->addExpression('1');
if (!$select->execute()->fetchField()) {
try {
$insert = $this->connection->insert($this->table)->fields($this->insertFields);
if ($this->defaultFields) {
$insert->useDefaults($this->defaultFields);
}
$insert->execute();
return self::STATUS_INSERT;
}
$select = $this->connection->select($this->conditionTable)
->condition($this->condition)
->forUpdate();
$select->addExpression('1');
if (!$select->execute()->fetchField()) {
try {
$insert = $this->connection->insert($this->table)->fields($this->insertFields);
if ($this->defaultFields) {
$insert->useDefaults($this->defaultFields);
}
$insert->execute();
return MergeQuery::STATUS_INSERT;
catch (Exception $e) {
// The insert query failed, maybe it's because a racing insert query
// beat us in inserting the same row. Retry the select query, if it
// returns a row, ignore the error and continue with the update
// query below.
if (!$select->execute()->fetchField()) {
throw $e;
}
catch (Exception $e) {
// The insert query failed, maybe it's because a racing insert query
// beat us in inserting the same row. Retry the select query, if it
// returns a row, ignore the error and continue with the update
// query below.
if (!$select->execute()->fetchField()) {
throw $e;
}
}
}
if ($this->needsUpdate) {
$update = $this->connection->update($this->table)
->fields($this->updateFields)
->condition($this->condition);
if ($this->expressionFields) {
foreach ($this->expressionFields as $field => $data) {
$update->expression($field, $data['expression'], $data['arguments']);
}
}
$update->execute();
return MergeQuery::STATUS_UPDATE;
}
}
catch (Exception $e) {
// Something really wrong happened here, bubble up the exception to the
// caller.
$transaction->rollback();
throw $e;
}
// Transaction commits here where $transaction looses scope.
if ($this->needsUpdate) {
$update = $this->connection->update($this->table)
->fields($this->updateFields)
->condition($this->condition);
if ($this->expressionFields) {
foreach ($this->expressionFields as $field => $data) {
$update->expression($field, $data['expression'], $data['arguments']);
}
}
$update->execute();
return self::STATUS_UPDATE;
}
}
}

View File

@ -596,7 +596,7 @@ class SelectQueryExtender implements SelectQueryInterface {
public function hasAnyTag() {
$args = func_get_args();
return call_user_func_array(array($this->query, 'hasAnyTags'), $args);
return call_user_func_array(array($this->query, 'hasAnyTag'), $args);
}
public function addMetaData($key, $object) {

View File

@ -250,7 +250,7 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
$prefixes[$tablename] = '';
$this->setPrefix($prefixes);
$this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE ' . $tablename . ' AS SELECT', $query), $args, $options);
$this->query('CREATE TEMPORARY TABLE ' . $tablename . ' AS ' . $query, $args, $options);
return $tablename;
}

View File

@ -41,7 +41,8 @@ class InsertQuery_sqlite extends InsertQuery {
// If we're selecting from a SelectQuery, finish building the query and
// pass it back, as any remaining options are irrelevant.
if (!empty($this->fromQuery)) {
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $this->insertFields) . ') ' . $this->fromQuery;
$insert_fields_string = $this->insertFields ? ' (' . implode(', ', $this->insertFields) . ') ' : ' ';
return $comments . 'INSERT INTO {' . $this->table . '}' . $insert_fields_string . $this->fromQuery;
}
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $this->insertFields) . ') VALUES (' . implode(', ', $placeholders) . ')';

View File

@ -154,18 +154,6 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
*/
public function load($ids = array(), $conditions = array()) {
$entities = array();
# PATCH http://drupal.org/node/1003788#comment-5195682
// Clean the $ids array to remove non-integer values that can be passed
// in from various sources, including menu callbacks.
if (is_array($ids)) {
foreach ($ids as $key => $id) {
if (empty($id) || ((string) $id !== (string) (int) $id)) {
unset($ids[$key]);
}
}
}
# endpatch
// Revisions are not statically cached, and require a different query to
// other conditions, so separate the revision id into its own variable.
@ -372,9 +360,23 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
// This ensures the same behavior whether loading from memory or database.
if ($conditions) {
foreach ($entities as $entity) {
$entity_values = (array) $entity;
if (array_diff_assoc($conditions, $entity_values)) {
unset($entities[$entity->{$this->idKey}]);
// Iterate over all conditions and compare them to the entity
// properties. We cannot use array_diff_assoc() here since the
// conditions can be nested arrays, too.
foreach ($conditions as $property_name => $condition) {
if (is_array($condition)) {
// Multiple condition values for one property are treated as OR
// operation: only if the value is not at all in the condition array
// we remove the entity.
if (!in_array($entity->{$property_name}, $condition)) {
unset($entities[$entity->{$this->idKey}]);
continue 2;
}
}
elseif ($condition != $entity->{$property_name}) {
unset($entities[$entity->{$this->idKey}]);
continue 2;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@
* Maps PHP error constants to watchdog severity levels.
*
* The error constants are documented at
* http://php.net/manual/en/errorfunc.constants.php
* http://php.net/manual/errorfunc.constants.php
*
* @ingroup logging_severity_levels
*/

View File

@ -470,8 +470,11 @@ function file_ensure_htaccess() {
* @param $private
* FALSE indicates that $directory should be an open and public directory.
* The default is TRUE which indicates a private and protected directory.
* @param $force_overwrite
* Set to TRUE to attempt to overwrite the existing .htaccess file if one is
* already present. Defaults to FALSE.
*/
function file_create_htaccess($directory, $private = TRUE) {
function file_create_htaccess($directory, $private = TRUE, $force_overwrite = FALSE) {
if (file_uri_scheme($directory)) {
$directory = file_stream_wrapper_uri_normalize($directory);
}
@ -480,19 +483,12 @@ function file_create_htaccess($directory, $private = TRUE) {
}
$htaccess_path = $directory . '/.htaccess';
if (file_exists($htaccess_path)) {
if (file_exists($htaccess_path) && !$force_overwrite) {
// Short circuit if the .htaccess file already exists.
return;
}
if ($private) {
// Private .htaccess file.
$htaccess_lines = "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006\nDeny from all\nOptions None\nOptions +FollowSymLinks";
}
else {
// Public .htaccess file.
$htaccess_lines = "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006\nOptions None\nOptions +FollowSymLinks";
}
$htaccess_lines = file_htaccess_lines($private);
// Write the .htaccess file.
if (file_put_contents($htaccess_path, $htaccess_lines)) {
@ -504,6 +500,45 @@ function file_create_htaccess($directory, $private = TRUE) {
}
}
/**
* Returns the standard .htaccess lines that Drupal writes to file directories.
*
* @param $private
* (Optional) Set to FALSE to return the .htaccess lines for an open and
* public directory. The default is TRUE, which returns the .htaccess lines
* for a private and protected directory.
*
* @return
* A string representing the desired contents of the .htaccess file.
*
* @see file_create_htaccess()
*/
function file_htaccess_lines($private = TRUE) {
$lines = <<<EOF
# Turn off all options we don't need.
Options None
Options +FollowSymLinks
# Set the catch-all handler to prevent scripts from being executed.
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
<Files *>
# Override the handler again if we're run later in the evaluation list.
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003
</Files>
# If we know how to do it safely, disable the PHP engine entirely.
<IfModule mod_php5.c>
php_flag engine off
</IfModule>
EOF;
if ($private) {
$lines = "Deny from all\n\n" . $lines;
}
return $lines;
}
/**
* Loads file objects from the database.
*
@ -586,7 +621,11 @@ function file_save(stdClass $file) {
module_invoke_all('entity_update', $file, 'file');
}
// Clear internal properties.
unset($file->original);
// Clear the static loading cache.
entity_get_controller('file')->resetCache(array($file->fid));
return $file;
}
@ -719,10 +758,11 @@ function file_usage_delete(stdClass $file, $module, $type = NULL, $id = NULL, $c
* stored in the database. This is a powerful function that in many ways
* performs like an advanced version of copy().
* - Checks if $source and $destination are valid and readable/writable.
* - Checks that $source is not equal to $destination; if they are an error
* is reported.
* - If file already exists in $destination either the call will error out,
* replace the file or rename the file based on the $replace parameter.
* - If the $source and $destination are equal, the behavior depends on the
* $replace parameter. FILE_EXISTS_REPLACE will error out. FILE_EXISTS_RENAME
* will rename the file until the $destination is unique.
* - Adds the new file to the files database. If the source file is a
* temporary file, the resulting file will also be a temporary file. See
* file_save_upload() for details on temporary files.
@ -817,10 +857,11 @@ function file_valid_uri($uri) {
* This is a powerful function that in many ways performs like an advanced
* version of copy().
* - Checks if $source and $destination are valid and readable/writable.
* - Checks that $source is not equal to $destination; if they are an error
* is reported.
* - If file already exists in $destination either the call will error out,
* replace the file or rename the file based on the $replace parameter.
* - If the $source and $destination are equal, the behavior depends on the
* $replace parameter. FILE_EXISTS_REPLACE will error out. FILE_EXISTS_RENAME
* will rename the file until the $destination is unique.
* - Provides a fallback using realpaths if the move fails using stream
* wrappers. This can occur because PHP's copy() function does not properly
* support streams if safe_mode or open_basedir are enabled. See
@ -1108,7 +1149,7 @@ function file_munge_filename($filename, $extensions, $alerts = TRUE) {
// Allow potentially insecure uploads for very savvy users and admin
if (!variable_get('allow_insecure_uploads', 0)) {
// Remove any null bytes. See http://php.net/manual/en/security.filesystem.nullbytes.php
// Remove any null bytes. See http://php.net/manual/security.filesystem.nullbytes.php
$filename = str_replace(chr(0), '', $filename);
$whitelist = array_unique(explode(' ', trim($extensions)));
@ -1256,6 +1297,7 @@ function file_delete(stdClass $file, $force = FALSE) {
if (file_unmanaged_delete($file->uri)) {
db_delete('file_managed')->condition('fid', $file->fid)->execute();
db_delete('file_usage')->condition('fid', $file->fid)->execute();
entity_get_controller('file')->resetCache();
return TRUE;
}
return FALSE;
@ -1365,8 +1407,9 @@ function file_space_used($uid = NULL, $status = FILE_STATUS_PERMANENT) {
* Temporary files are periodically cleaned. To make the file a permanent file,
* assign the status and use file_save() to save the changes.
*
* @param $source
* A string specifying the filepath or URI of the uploaded file to save.
* @param $form_field_name
* A string that is the associative array key of the upload form element in
* the form array.
* @param $validators
* An optional, associative array of callback functions used to validate the
* file. See file_validate() for a full discussion of the array format.
@ -1377,9 +1420,9 @@ function file_space_used($uid = NULL, $status = FILE_STATUS_PERMANENT) {
* (Beware: this is not safe and should only be allowed for trusted users, if
* at all).
* @param $destination
* A string containing the URI $source should be copied to.
* This must be a stream wrapper URI. If this value is omitted, Drupal's
* temporary files scheme will be used ("temporary://").
* A string containing the URI that the file should be copied to. This must
* be a stream wrapper URI. If this value is omitted, Drupal's temporary
* files scheme will be used ("temporary://").
* @param $replace
* Replace behavior when the destination file already exists:
* - FILE_EXISTS_REPLACE: Replace the existing file.
@ -1397,45 +1440,45 @@ function file_space_used($uid = NULL, $status = FILE_STATUS_PERMANENT) {
* - source: Path to the file before it is moved.
* - destination: Path to the file after it is moved (same as 'uri').
*/
function file_save_upload($source, $validators = array(), $destination = FALSE, $replace = FILE_EXISTS_RENAME) {
function file_save_upload($form_field_name, $validators = array(), $destination = FALSE, $replace = FILE_EXISTS_RENAME) {
global $user;
static $upload_cache;
// Return cached objects without processing since the file will have
// already been processed and the paths in _FILES will be invalid.
if (isset($upload_cache[$source])) {
return $upload_cache[$source];
if (isset($upload_cache[$form_field_name])) {
return $upload_cache[$form_field_name];
}
// Make sure there's an upload to process.
if (empty($_FILES['files']['name'][$source])) {
if (empty($_FILES['files']['name'][$form_field_name])) {
return NULL;
}
// Check for file upload errors and return FALSE if a lower level system
// error occurred. For a complete list of errors:
// See http://php.net/manual/en/features.file-upload.errors.php.
switch ($_FILES['files']['error'][$source]) {
// See http://php.net/manual/features.file-upload.errors.php.
switch ($_FILES['files']['error'][$form_field_name]) {
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
drupal_set_message(t('The file %file could not be saved, because it exceeds %maxsize, the maximum allowed size for uploads.', array('%file' => $_FILES['files']['name'][$source], '%maxsize' => format_size(file_upload_max_size()))), 'error');
drupal_set_message(t('The file %file could not be saved, because it exceeds %maxsize, the maximum allowed size for uploads.', array('%file' => $_FILES['files']['name'][$form_field_name], '%maxsize' => format_size(file_upload_max_size()))), 'error');
return FALSE;
case UPLOAD_ERR_PARTIAL:
case UPLOAD_ERR_NO_FILE:
drupal_set_message(t('The file %file could not be saved, because the upload did not complete.', array('%file' => $_FILES['files']['name'][$source])), 'error');
drupal_set_message(t('The file %file could not be saved, because the upload did not complete.', array('%file' => $_FILES['files']['name'][$form_field_name])), 'error');
return FALSE;
case UPLOAD_ERR_OK:
// Final check that this is a valid upload, if it isn't, use the
// default error handler.
if (is_uploaded_file($_FILES['files']['tmp_name'][$source])) {
if (is_uploaded_file($_FILES['files']['tmp_name'][$form_field_name])) {
break;
}
// Unknown error
default:
drupal_set_message(t('The file %file could not be saved. An unknown error has occurred.', array('%file' => $_FILES['files']['name'][$source])), 'error');
drupal_set_message(t('The file %file could not be saved. An unknown error has occurred.', array('%file' => $_FILES['files']['name'][$form_field_name])), 'error');
return FALSE;
}
@ -1443,10 +1486,10 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
$file = new stdClass();
$file->uid = $user->uid;
$file->status = 0;
$file->filename = trim(drupal_basename($_FILES['files']['name'][$source]), '.');
$file->uri = $_FILES['files']['tmp_name'][$source];
$file->filename = trim(drupal_basename($_FILES['files']['name'][$form_field_name]), '.');
$file->uri = $_FILES['files']['tmp_name'][$form_field_name];
$file->filemime = file_get_mimetype($file->filename);
$file->filesize = $_FILES['files']['size'][$source];
$file->filesize = $_FILES['files']['size'][$form_field_name];
$extensions = '';
if (isset($validators['file_validate_extensions'])) {
@ -1503,7 +1546,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
return FALSE;
}
$file->source = $source;
$file->source = $form_field_name;
// A URI may already have a trailing slash or look like "public://".
if (substr($destination, -1) != '/') {
$destination .= '/';
@ -1512,7 +1555,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
// If file_destination() returns FALSE then $replace == FILE_EXISTS_ERROR and
// there's an existing file so we need to bail.
if ($file->destination === FALSE) {
drupal_set_message(t('The file %source could not be uploaded because a file by that name already exists in the destination %directory.', array('%source' => $source, '%directory' => $destination)), 'error');
drupal_set_message(t('The file %source could not be uploaded because a file by that name already exists in the destination %directory.', array('%source' => $form_field_name, '%directory' => $destination)), 'error');
return FALSE;
}
@ -1531,7 +1574,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
else {
$message .= ' ' . array_pop($errors);
}
form_set_error($source, $message);
form_set_error($form_field_name, $message);
return FALSE;
}
@ -1539,8 +1582,8 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
// directory. This overcomes open_basedir restrictions for future file
// operations.
$file->uri = $file->destination;
if (!drupal_move_uploaded_file($_FILES['files']['tmp_name'][$source], $file->uri)) {
form_set_error($source, t('File upload error. Could not move uploaded file.'));
if (!drupal_move_uploaded_file($_FILES['files']['tmp_name'][$form_field_name], $file->uri)) {
form_set_error($form_field_name, t('File upload error. Could not move uploaded file.'));
watchdog('file', 'Upload error. Could not move uploaded file %file to destination %destination.', array('%file' => $file->filename, '%destination' => $file->uri));
return FALSE;
}
@ -1560,7 +1603,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
// If we made it this far it's safe to record this file in the database.
if ($file = file_save($file)) {
// Add file to the cache.
$upload_cache[$source] = $file;
$upload_cache[$form_field_name] = $file;
return $file;
}
return FALSE;
@ -2177,7 +2220,7 @@ function drupal_chmod($uri, $mode = NULL) {
* @param $uri
* A URI or pathname.
* @param $context
* Refer to http://php.net/manual/en/ref.stream.php
* Refer to http://php.net/manual/ref.stream.php
*
* @return
* Boolean TRUE on success, or FALSE on failure.
@ -2310,7 +2353,7 @@ function drupal_basename($uri, $suffix = NULL) {
* @param $recursive
* Default to FALSE.
* @param $context
* Refer to http://php.net/manual/en/ref.stream.php
* Refer to http://php.net/manual/ref.stream.php
*
* @return
* Boolean TRUE on success, or FALSE on failure.
@ -2341,7 +2384,7 @@ function drupal_mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) {
* @param $uri
* A URI or pathname.
* @param $context
* Refer to http://php.net/manual/en/ref.stream.php
* Refer to http://php.net/manual/ref.stream.php
*
* @return
* Boolean TRUE on success, or FALSE on failure.

View File

@ -82,11 +82,11 @@ class FileTransferFTPExtension extends FileTransferFTP implements FileTransferCh
if (!$list) {
$list = array();
}
foreach ($list as $item){
foreach ($list as $item) {
if ($item == '.' || $item == '..') {
continue;
}
if (@ftp_chdir($this->connection, $item)){
if (@ftp_chdir($this->connection, $item)) {
ftp_cdup($this->connection);
$this->removeDirectory(ftp_pwd($this->connection) . '/' . $item);
}
@ -122,7 +122,7 @@ class FileTransferFTPExtension extends FileTransferFTP implements FileTransferCh
function chmodJailed($path, $mode, $recursive) {
if (!ftp_chmod($this->connection, $mode, $path)) {
throw new FileTransferException("Unable to set permissions on %file", NULL, array ('%file' => $path));
throw new FileTransferException("Unable to set permissions on %file", NULL, array('%file' => $path));
}
if ($this->isDirectory($path) && $recursive) {
$filelist = @ftp_nlist($this->connection, $path);

View File

@ -15,10 +15,9 @@
* reference the form builder function using \@see. For examples, of this see
* system_modules_uninstall() or user_pass(), the latter of which has the
* following in its doxygen documentation:
*
* \@ingroup forms
* \@see user_pass_validate().
* \@see user_pass_submit().
* - \@ingroup forms
* - \@see user_pass_validate()
* - \@see user_pass_submit()
*
* @}
*/
@ -168,6 +167,12 @@ function drupal_get_form($form_id) {
* processed.
* - base_form_id: Identification for a base form, as declared in a
* hook_forms() implementation.
* - immutable: If this flag is set to TRUE, a new form build id is
* generated when the form is loaded from the cache. If it is subsequently
* saved to the cache again, it will have another cache id and therefore
* the original form and form-state will remain unaltered. This is
* important when page caching is enabled in order to prevent form state
* from leaking between anonymous users.
* - rebuild_info: Internal. Similar to 'build_info', but pertaining to
* drupal_rebuild_form().
* - rebuild: Normally, after the entire form processing is completed and
@ -235,6 +240,12 @@ function drupal_get_form($form_id) {
* likely to occur during Ajax operations.
* - programmed: If TRUE, the form was submitted programmatically, usually
* invoked via drupal_form_submit(). Defaults to FALSE.
* - programmed_bypass_access_check: If TRUE, programmatic form submissions
* are processed without taking #access into account. Set this to FALSE
* when submitting a form programmatically with values that may have been
* input by the user executing the current request; this will cause #access
* to be respected as it would on a normal form submission. Defaults to
* TRUE.
* - process_input: Boolean flag. TRUE signifies correct form submission.
* This is always TRUE for programmed forms coming from drupal_form_submit()
* (see 'programmed' key), or if the form_id coming from the $_POST data is
@ -402,6 +413,7 @@ function form_state_defaults() {
'submitted' => FALSE,
'executed' => FALSE,
'programmed' => FALSE,
'programmed_bypass_access_check' => TRUE,
'cache'=> FALSE,
'method' => 'post',
'groups' => array(),
@ -452,17 +464,25 @@ function drupal_rebuild_form($form_id, &$form_state, $old_form = NULL) {
$form = drupal_retrieve_form($form_id, $form_state);
// If only parts of the form will be returned to the browser (e.g., Ajax or
// RIA clients), re-use the old #build_id to not require client-side code to
// manually update the hidden 'build_id' input element.
// RIA clients), or if the form already had a new build ID regenerated when it
// was retrieved from the form cache, reuse the existing #build_id.
// Otherwise, a new #build_id is generated, to not clobber the previous
// build's data in the form cache; also allowing the user to go back to an
// earlier build, make changes, and re-submit.
// @see drupal_prepare_form()
if (isset($old_form['#build_id']) && !empty($form_state['rebuild_info']['copy']['#build_id'])) {
$enforce_old_build_id = isset($old_form['#build_id']) && !empty($form_state['rebuild_info']['copy']['#build_id']);
$old_form_is_mutable_copy = isset($old_form['#build_id_old']);
if ($enforce_old_build_id || $old_form_is_mutable_copy) {
$form['#build_id'] = $old_form['#build_id'];
if ($old_form_is_mutable_copy) {
$form['#build_id_old'] = $old_form['#build_id_old'];
}
}
else {
$form['#build_id'] = 'form-' . drupal_hash_base64(uniqid(mt_rand(), TRUE) . mt_rand());
if (isset($old_form['#build_id'])) {
$form['#build_id_old'] = $old_form['#build_id'];
}
$form['#build_id'] = 'form-' . drupal_random_key();
}
// #action defaults to request_uri(), but in case of Ajax and other partial
@ -516,6 +536,15 @@ function form_get_cache($form_build_id, &$form_state) {
}
}
}
// Generate a new #build_id if the cached form was rendered on a cacheable
// page.
if (!empty($form_state['build_info']['immutable'])) {
$form['#build_id_old'] = $form['#build_id'];
$form['#build_id'] = 'form-' . drupal_random_key();
$form['form_build_id']['#value'] = $form['#build_id'];
$form['form_build_id']['#id'] = $form['#build_id'];
unset($form_state['build_info']['immutable']);
}
return $form;
}
}
@ -528,15 +557,28 @@ function form_set_cache($form_build_id, $form, $form_state) {
// 6 hours cache life time for forms should be plenty.
$expire = 21600;
// Ensure that the form build_id embedded in the form structure is the same as
// the one passed in as a parameter. This is an additional safety measure to
// prevent legacy code operating directly with form_get_cache and
// form_set_cache from accidentally overwriting immutable form state.
if ($form['#build_id'] != $form_build_id) {
watchdog('form', 'Form build-id mismatch detected while attempting to store a form in the cache.', array(), WATCHDOG_ERROR);
return;
}
// Cache form structure.
if (isset($form)) {
if ($GLOBALS['user']->uid) {
$form['#cache_token'] = drupal_get_token();
}
unset($form['#build_id_old']);
cache_set('form_' . $form_build_id, $form, 'cache_form', REQUEST_TIME + $expire);
}
// Cache form state.
if (variable_get('cache', 0) && drupal_page_is_cacheable()) {
$form_state['build_info']['immutable'] = TRUE;
}
if ($data = array_diff_key($form_state, array_flip(form_state_keys_no_cache()))) {
cache_set('form_state_' . $form_build_id, $data, 'cache_form', REQUEST_TIME + $expire);
}
@ -977,7 +1019,7 @@ function drupal_prepare_form($form_id, &$form, &$form_state) {
// @see drupal_build_form()
// @see drupal_rebuild_form()
if (!isset($form['#build_id'])) {
$form['#build_id'] = 'form-' . drupal_hash_base64(uniqid(mt_rand(), TRUE) . mt_rand());
$form['#build_id'] = 'form-' . drupal_random_key();
}
$form['form_build_id'] = array(
'#type' => 'hidden',
@ -1129,6 +1171,12 @@ function drupal_validate_form($form_id, &$form, &$form_state) {
// Setting this error will cause the form to fail validation.
form_set_error('form_token', t('The form has become outdated. Copy any unsaved work in the form below and then <a href="@link">reload this page</a>.', array('@link' => $url)));
// Stop here and don't run any further validation handlers, because they
// could invoke non-safe operations which opens the door for CSRF
// vulnerabilities.
$validated_forms[$form_id] = TRUE;
return;
}
}
@ -1979,7 +2027,7 @@ function _form_builder_handle_input_element($form_id, &$element, &$form_state) {
// #access=FALSE on an element usually allow access for some users, so forms
// submitted with drupal_form_submit() may bypass access restriction and be
// treated as high-privilege users instead.
$process_input = empty($element['#disabled']) && ($form_state['programmed'] || ($form_state['process_input'] && (!isset($element['#access']) || $element['#access'])));
$process_input = empty($element['#disabled']) && (($form_state['programmed'] && $form_state['programmed_bypass_access_check']) || ($form_state['process_input'] && (!isset($element['#access']) || $element['#access'])));
// Set the element's #value property.
if (!isset($element['#value']) && !array_key_exists('#value', $element)) {
@ -3052,8 +3100,7 @@ function form_process_radios($element) {
* @param $variables
* An associative array containing:
* - element: An associative array containing the properties of the element.
* Properties used: #title, #value, #return_value, #description, #required,
* #attributes, #checked.
* Properties used: #id, #name, #attributes, #checked, #return_value.
*
* @ingroup themeable
*/
@ -4245,7 +4292,7 @@ function element_validate_number($element, &$form_state) {
* returns any user input in the 'results' or 'message' keys of $context,
* it must also sanitize them first.
*
* Sample batch operations:
* Sample callback_batch_operation():
* @code
* // Simple and artificial: load a node of a given type for a given user
* function my_function_1($uid, $type, &$context) {
@ -4297,7 +4344,7 @@ function element_validate_number($element, &$form_state) {
* }
* @endcode
*
* Sample 'finished' callback:
* Sample callback_batch_finished():
* @code
* function batch_test_finished($success, $results, $operations) {
* // The 'success' parameter means no fatal PHP errors were detected. All
@ -4336,12 +4383,14 @@ function element_validate_number($element, &$form_state) {
* @param $batch_definition
* An associative array defining the batch, with the following elements (all
* are optional except as noted):
* - operations: (required) Array of function calls to be performed.
* - operations: (required) Array of operations to be performed, where each
* item is an array consisting of the name of an implementation of
* callback_batch_operation() and an array of parameter.
* Example:
* @code
* array(
* array('my_function_1', array($arg1)),
* array('my_function_2', array($arg2_1, $arg2_2)),
* array('callback_batch_operation_1', array($arg1)),
* array('callback_batch_operation_2', array($arg2_1, $arg2_2)),
* )
* @endcode
* - title: A safe, translated string to use as the title for the progress
@ -4353,10 +4402,10 @@ function element_validate_number($element, &$form_state) {
* @elapsed. Defaults to t('Completed @current of @total.').
* - error_message: Message displayed if an error occurred while processing
* the batch. Defaults to t('An error has occurred.').
* - finished: Name of a function to be executed after the batch has
* completed. This should be used to perform any result massaging that may
* be needed, and possibly save data in $_SESSION for display after final
* page redirection.
* - finished: Name of an implementation of callback_batch_finished(). This is
* executed after the batch has completed. This should be used to perform
* any result massaging that may be needed, and possibly save data in
* $_SESSION for display after final page redirection.
* - file: Path to the file containing the definitions of the 'operations' and
* 'finished' functions, for instance if they don't reside in the main
* .module file. The path should be relative to base_path(), and thus should

View File

@ -692,6 +692,21 @@ function install_full_redirect_url($install_state) {
*/
function install_display_output($output, $install_state) {
drupal_page_header();
// Prevent install.php from being indexed when installed in a sub folder.
// robots.txt rules are not read if the site is within domain.com/subfolder
// resulting in /subfolder/install.php being found through search engines.
// When settings.php is writeable this can be used via an external database
// leading a malicious user to gain php access to the server.
$noindex_meta_tag = array(
'#tag' => 'meta',
'#attributes' => array(
'name' => 'robots',
'content' => 'noindex, nofollow',
),
);
drupal_add_html_head($noindex_meta_tag, 'install_meta_robots');
// Only show the task list if there is an active task; otherwise, the page
// request has ended before tasks have even been started, so there is nothing
// meaningful to show.
@ -766,6 +781,15 @@ function install_system_module(&$install_state) {
// Install system.module.
drupal_install_system();
// Call file_ensure_htaccess() to ensure that all of Drupal's standard
// directories (e.g., the public and private files directories) have
// appropriate .htaccess files. These directories will have already been
// created by this point in the installer, since Drupal creates them during
// the install_verify_requirements() task. Note that we cannot call
// file_ensure_htaccess() any earlier than this, since it relies on
// system.module in order to work.
file_ensure_htaccess();
// Enable the user module so that sessions can be recorded during the
// upcoming bootstrap step.
module_enable(array('user'), FALSE);
@ -981,7 +1005,7 @@ function install_settings_form_submit($form, &$form_state) {
'required' => TRUE,
);
$settings['drupal_hash_salt'] = array(
'value' => drupal_hash_base64(drupal_random_bytes(55)),
'value' => drupal_random_key(),
'required' => TRUE,
);
drupal_rewrite_settings($settings);

View File

@ -1134,7 +1134,6 @@ function st($string, array $args = array(), array $options = array()) {
}
}
require_once DRUPAL_ROOT . '/includes/theme.inc';
// Transform arguments before inserting them
foreach ($args as $key => $value) {
switch ($key[0]) {

View File

@ -53,6 +53,7 @@ function _country_get_predefined_list() {
'BM' => $t('Bermuda'),
'BN' => $t('Brunei'),
'BO' => $t('Bolivia'),
'BQ' => $t('Caribbean Netherlands'),
'BR' => $t('Brazil'),
'BS' => $t('Bahamas'),
'BT' => $t('Bhutan'),
@ -74,8 +75,8 @@ function _country_get_predefined_list() {
'CO' => $t('Colombia'),
'CR' => $t('Costa Rica'),
'CU' => $t('Cuba'),
'CW' => $t('Curaçao'),
'CV' => $t('Cape Verde'),
'CW' => $t('Curaçao'),
'CX' => $t('Christmas Island'),
'CY' => $t('Cyprus'),
'CZ' => $t('Czech Republic'),
@ -230,8 +231,10 @@ function _country_get_predefined_list() {
'SN' => $t('Senegal'),
'SO' => $t('Somalia'),
'SR' => $t('Suriname'),
'SS' => $t('South Sudan'),
'ST' => $t('Sao Tome and Principe'),
'SV' => $t('El Salvador'),
'SX' => $t('Sint Maarten'),
'SY' => $t('Syria'),
'SZ' => $t('Swaziland'),
'TC' => $t('Turks and Caicos Islands'),

View File

@ -78,7 +78,7 @@ define('LANGUAGE_NEGOTIATION_DEFAULT', 'language-default');
* function mymodule_language_negotiation_info_alter(&$negotiation_info) {
* // Replace the core function with our own function.
* module_load_include('language', 'inc', 'language.negotiation');
* $negotiation_info[LANGUAGE_NEGOTIATION_URL]['callbacks']['negotiation'] = 'mymodule_from_url';
* $negotiation_info[LANGUAGE_NEGOTIATION_URL]['callbacks']['language'] = 'mymodule_from_url';
* $negotiation_info[LANGUAGE_NEGOTIATION_URL]['file'] = drupal_get_path('module', 'mymodule') . '/mymodule.module';
* }
*
@ -94,7 +94,6 @@ define('LANGUAGE_NEGOTIATION_DEFAULT', 'language-default');
* }
* return $langcode;
* }
* ?>
* @endcode
*
* For more information, see
@ -314,7 +313,7 @@ function language_negotiation_get_switch_links($type, $path) {
}
/**
* Removes any unused language negotation providers from the configuration.
* Removes any unused language negotiation providers from the configuration.
*/
function language_negotiation_purge() {
// Ensure that we are getting the defined language negotiation information. An

View File

@ -339,13 +339,13 @@ interface MailSystemInterface {
*
* We deliberately use LF rather than CRLF, see drupal_mail().
*
* @param $text
* @param string $text
* The plain text to process.
* @param $indent (optional)
* @param string $indent (optional)
* A string to indent the text with. Only '>' characters are repeated on
* subsequent wrapped lines. Others are replaced by spaces.
*
* @return
* @return string
* The content of the email as a string with formatting applied.
*/
function drupal_wrap_mail($text, $indent = '') {
@ -356,8 +356,9 @@ function drupal_wrap_mail($text, $indent = '') {
$soft = strpos($clean_indent, ' ') === FALSE;
// Check if the string has line breaks.
if (strpos($text, "\n") !== FALSE) {
// Remove trailing spaces to make existing breaks hard.
$text = preg_replace('/ +\n/m', "\n", $text);
// Remove trailing spaces to make existing breaks hard, but leave signature
// marker untouched (RFC 3676, Section 4.3).
$text = preg_replace('/(?(?<!^--) +\n| +\n)/m', "\n", $text);
// Wrap each line at the needed width.
$lines = explode("\n", $text);
array_walk($lines, '_drupal_wrap_mail_line', array('soft' => $soft, 'length' => strlen($indent)));
@ -563,7 +564,7 @@ function drupal_html_to_text($string, $allowed_tags = NULL) {
*/
function _drupal_wrap_mail_line(&$line, $key, $values) {
// Use soft-breaks only for purely quoted or unindented text.
$line = wordwrap($line, 77 - $values['length'], $values['soft'] ? " \n" : "\n");
$line = wordwrap($line, 77 - $values['length'], $values['soft'] ? " \n" : "\n");
// Break really long words at the maximum width allowed.
$line = wordwrap($line, 996 - $values['length'], $values['soft'] ? " \n" : "\n");
}

View File

@ -1000,7 +1000,7 @@ function menu_tree($menu_name) {
}
/**
* Returns a rendered menu tree.
* Returns an output structure for rendering a menu tree.
*
* The menu item's LI element is given one of the following classes:
* - expanded: The menu item is showing its submenu.
@ -1926,13 +1926,21 @@ function menu_local_tasks($level = 0) {
}
// Get all tabs (also known as local tasks) and the root page.
$result = db_select('menu_router', NULL, array('fetch' => PDO::FETCH_ASSOC))
->fields('menu_router')
->condition('tab_root', $router_item['tab_root'])
->condition('context', MENU_CONTEXT_INLINE, '<>')
->orderBy('weight')
->orderBy('title')
->execute();
$cid = 'local_tasks:' . $router_item['tab_root'];
if ($cache = cache_get($cid, 'cache_menu')) {
$result = $cache->data;
}
else {
$result = db_select('menu_router', NULL, array('fetch' => PDO::FETCH_ASSOC))
->fields('menu_router')
->condition('tab_root', $router_item['tab_root'])
->condition('context', MENU_CONTEXT_INLINE, '<>')
->orderBy('weight')
->orderBy('title')
->execute()
->fetchAll();
cache_set($cid, $result, 'cache_menu');
}
$map = $router_item['original_map'];
$children = array();
$tasks = array();

View File

@ -560,8 +560,8 @@ function drupal_valid_path($path, $dynamic_allowed = FALSE) {
elseif ($dynamic_allowed && preg_match('/\/\%/', $path)) {
// Path is dynamic (ie 'user/%'), so check directly against menu_router table.
if ($item = db_query("SELECT * FROM {menu_router} where path = :path", array(':path' => $path))->fetchAssoc()) {
$item['link_path'] = $form_item['link_path'];
$item['link_title'] = $form_item['link_title'];
$item['link_path'] = $item['path'];
$item['link_title'] = $item['title'];
$item['external'] = FALSE;
$item['options'] = '';
_menu_link_translate($item);

View File

@ -10,7 +10,7 @@
* @{
* The code registry engine.
*
* Drupal maintains an internal registry of all functions or classes in the
* Drupal maintains an internal registry of all interfaces or classes in the
* system, allowing it to lazy-load code files as needed (reducing the amount
* of code that must be parsed on each request).
*/
@ -120,7 +120,10 @@ function registry_get_parsed_files() {
}
/**
* Parse all files that have changed since the registry was last built, and save their function and class listings.
* Parse all changed files and save their interface and class listings.
*
* Parse all files that have changed since the registry was last built, and save
* their interface and class listings.
*
* @param $files
* The list of files to check and parse.
@ -149,7 +152,7 @@ function _registry_parse_files($files) {
}
/**
* Parse a file and save its function and class listings.
* Parse a file and save its interface and class listings.
*
* @param $filename
* Name of the file we are going to parse.

View File

@ -263,10 +263,10 @@ function drupal_session_initialize() {
// Less random sessions (which are much faster to generate) are used for
// anonymous users than are generated in drupal_session_regenerate() when
// a user becomes authenticated.
session_id(drupal_hash_base64(uniqid(mt_rand(), TRUE)));
session_id(drupal_random_key());
if ($is_https && variable_get('https', FALSE)) {
$insecure_session_name = substr(session_name(), 1);
$session_id = drupal_hash_base64(uniqid(mt_rand(), TRUE));
$session_id = drupal_random_key();
$_COOKIE[$insecure_session_name] = $session_id;
}
}
@ -360,7 +360,7 @@ function drupal_session_regenerate() {
$old_insecure_session_id = $_COOKIE[$insecure_session_name];
}
$params = session_get_cookie_params();
$session_id = drupal_hash_base64(uniqid(mt_rand(), TRUE) . drupal_random_bytes(55));
$session_id = drupal_random_key();
// If a session cookie lifetime is set, the session will expire
// $params['lifetime'] seconds from the current request. If it is not set,
// it will expire when the browser is closed.
@ -372,7 +372,7 @@ function drupal_session_regenerate() {
if (drupal_session_started()) {
$old_session_id = session_id();
}
session_id(drupal_hash_base64(uniqid(mt_rand(), TRUE) . drupal_random_bytes(55)));
session_id(drupal_random_key());
if (isset($old_session_id)) {
$params = session_get_cookie_params();

View File

@ -93,7 +93,7 @@ define('STREAM_WRAPPERS_LOCAL_NORMAL', STREAM_WRAPPERS_LOCAL | STREAM_WRAPPERS_N
/**
* Generic PHP stream wrapper interface.
*
* @see http://www.php.net/manual/en/class.streamwrapper.php
* @see http://www.php.net/manual/class.streamwrapper.php
*/
interface StreamWrapperInterface {
public function stream_open($uri, $mode, $options, &$opened_url);
@ -401,7 +401,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* @return
* Returns TRUE if file was opened successfully.
*
* @see http://php.net/manual/en/streamwrapper.stream-open.php
* @see http://php.net/manual/streamwrapper.stream-open.php
*/
public function stream_open($uri, $mode, $options, &$opened_path) {
$this->uri = $uri;
@ -429,7 +429,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* @return
* Always returns TRUE at the present time.
*
* @see http://php.net/manual/en/streamwrapper.stream-lock.php
* @see http://php.net/manual/streamwrapper.stream-lock.php
*/
public function stream_lock($operation) {
if (in_array($operation, array(LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB))) {
@ -448,7 +448,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* @return
* The string that was read, or FALSE in case of an error.
*
* @see http://php.net/manual/en/streamwrapper.stream-read.php
* @see http://php.net/manual/streamwrapper.stream-read.php
*/
public function stream_read($count) {
return fread($this->handle, $count);
@ -463,7 +463,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* @return
* The number of bytes written (integer).
*
* @see http://php.net/manual/en/streamwrapper.stream-write.php
* @see http://php.net/manual/streamwrapper.stream-write.php
*/
public function stream_write($data) {
return fwrite($this->handle, $data);
@ -475,7 +475,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* @return
* TRUE if end-of-file has been reached.
*
* @see http://php.net/manual/en/streamwrapper.stream-eof.php
* @see http://php.net/manual/streamwrapper.stream-eof.php
*/
public function stream_eof() {
return feof($this->handle);
@ -492,7 +492,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* @return
* TRUE on success.
*
* @see http://php.net/manual/en/streamwrapper.stream-seek.php
* @see http://php.net/manual/streamwrapper.stream-seek.php
*/
public function stream_seek($offset, $whence) {
// fseek returns 0 on success and -1 on a failure.
@ -506,7 +506,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* @return
* TRUE if data was successfully stored (or there was no data to store).
*
* @see http://php.net/manual/en/streamwrapper.stream-flush.php
* @see http://php.net/manual/streamwrapper.stream-flush.php
*/
public function stream_flush() {
return fflush($this->handle);
@ -518,7 +518,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* @return
* The current offset in bytes from the beginning of file.
*
* @see http://php.net/manual/en/streamwrapper.stream-tell.php
* @see http://php.net/manual/streamwrapper.stream-tell.php
*/
public function stream_tell() {
return ftell($this->handle);
@ -531,7 +531,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* An array with file status, or FALSE in case of an error - see fstat()
* for a description of this array.
*
* @see http://php.net/manual/en/streamwrapper.stream-stat.php
* @see http://php.net/manual/streamwrapper.stream-stat.php
*/
public function stream_stat() {
return fstat($this->handle);
@ -543,7 +543,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* @return
* TRUE if stream was successfully closed.
*
* @see http://php.net/manual/en/streamwrapper.stream-close.php
* @see http://php.net/manual/streamwrapper.stream-close.php
*/
public function stream_close() {
return fclose($this->handle);
@ -558,7 +558,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* @return
* TRUE if resource was successfully deleted.
*
* @see http://php.net/manual/en/streamwrapper.unlink.php
* @see http://php.net/manual/streamwrapper.unlink.php
*/
public function unlink($uri) {
$this->uri = $uri;
@ -576,7 +576,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* @return
* TRUE if file was successfully renamed.
*
* @see http://php.net/manual/en/streamwrapper.rename.php
* @see http://php.net/manual/streamwrapper.rename.php
*/
public function rename($from_uri, $to_uri) {
return rename($this->getLocalPath($from_uri), $this->getLocalPath($to_uri));
@ -622,7 +622,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* @return
* TRUE if directory was successfully created.
*
* @see http://php.net/manual/en/streamwrapper.mkdir.php
* @see http://php.net/manual/streamwrapper.mkdir.php
*/
public function mkdir($uri, $mode, $options) {
$this->uri = $uri;
@ -654,7 +654,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* @return
* TRUE if directory was successfully removed.
*
* @see http://php.net/manual/en/streamwrapper.rmdir.php
* @see http://php.net/manual/streamwrapper.rmdir.php
*/
public function rmdir($uri, $options) {
$this->uri = $uri;
@ -678,7 +678,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* An array with file status, or FALSE in case of an error - see fstat()
* for a description of this array.
*
* @see http://php.net/manual/en/streamwrapper.url-stat.php
* @see http://php.net/manual/streamwrapper.url-stat.php
*/
public function url_stat($uri, $flags) {
$this->uri = $uri;
@ -704,7 +704,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* @return
* TRUE on success.
*
* @see http://php.net/manual/en/streamwrapper.dir-opendir.php
* @see http://php.net/manual/streamwrapper.dir-opendir.php
*/
public function dir_opendir($uri, $options) {
$this->uri = $uri;
@ -719,7 +719,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* @return
* The next filename, or FALSE if there are no more files in the directory.
*
* @see http://php.net/manual/en/streamwrapper.dir-readdir.php
* @see http://php.net/manual/streamwrapper.dir-readdir.php
*/
public function dir_readdir() {
return readdir($this->handle);
@ -731,7 +731,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* @return
* TRUE on success.
*
* @see http://php.net/manual/en/streamwrapper.dir-rewinddir.php
* @see http://php.net/manual/streamwrapper.dir-rewinddir.php
*/
public function dir_rewinddir() {
rewinddir($this->handle);
@ -747,7 +747,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
* @return
* TRUE on success.
*
* @see http://php.net/manual/en/streamwrapper.dir-closedir.php
* @see http://php.net/manual/streamwrapper.dir-closedir.php
*/
public function dir_closedir() {
closedir($this->handle);
@ -788,8 +788,6 @@ class DrupalPublicStreamWrapper extends DrupalLocalStreamWrapper {
*
* Provides support for storing privately accessible files with the Drupal file
* interface.
*
* Extends DrupalPublicStreamWrapper.
*/
class DrupalPrivateStreamWrapper extends DrupalLocalStreamWrapper {
/**

View File

@ -616,6 +616,13 @@ Drupal.ajax.prototype.commands = {
.removeClass('odd even')
.filter(':even').addClass('odd').end()
.filter(':odd').addClass('even');
},
/**
* Command to update a form's build ID.
*/
updateBuildId: function(ajax, response, status) {
$('input[name="form_build_id"][value="' + response['old'] + '"]').val(response['new']);
}
};

View File

@ -373,7 +373,7 @@ states.Trigger.states = {
checked: {
'change': function () {
return this.attr('checked');
return this.is(':checked');
}
},

View File

@ -7,8 +7,8 @@ files[] = aggregator.test
configure = admin/config/services/aggregator/settings
stylesheets[all][] = aggregator.css
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -260,6 +260,7 @@ function aggregator_schema() {
'primary key' => array('iid'),
'indexes' => array(
'fid' => array('fid'),
'timestamp' => array('timestamp'),
),
'foreign keys' => array(
'aggregator_feed' => array(
@ -325,6 +326,15 @@ function aggregator_update_7003() {
db_add_index('aggregator_feed', 'url', array(array('url', 255)));
}
/**
* Add index on timestamp.
*/
function aggregator_update_7004() {
if (!db_index_exists('aggregator_item', 'timestamp')) {
db_add_index('aggregator_item', 'timestamp', array('timestamp'));
}
}
/**
* @} End of "addtogroup updates-7.x-extra"
*/

View File

@ -288,6 +288,10 @@ EOF;
return $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'aggregator') . '/tests/aggregator_test_atom.xml';
}
function getHtmlEntitiesSample() {
return $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'aggregator') . '/tests/aggregator_test_title_entities.xml';
}
/**
* Creates sample article nodes.
*
@ -931,7 +935,7 @@ class AggregatorRenderingTestCase extends AggregatorTestCase {
// up.
$feed->block = 0;
aggregator_save_feed((array) $feed);
// It is nescessary to flush the cache after saving the number of items.
// It is necessary to flush the cache after saving the number of items.
drupal_flush_all_caches();
// Check that the block is no longer displayed.
$this->drupalGet('node');
@ -1016,4 +1020,15 @@ class FeedParserTestCase extends AggregatorTestCase {
$this->assertText('Some text.');
$this->assertEqual('urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a', db_query('SELECT guid FROM {aggregator_item} WHERE link = :link', array(':link' => 'http://example.org/2003/12/13/atom03'))->fetchField(), 'Atom entry id element is parsed correctly.');
}
/**
* Tests a feed that uses HTML entities in item titles.
*/
function testHtmlEntitiesSample() {
$feed = $this->createFeed($this->getHtmlEntitiesSample());
aggregator_refresh($feed);
$this->drupalGet('aggregator/sources/' . $feed->fid);
$this->assertResponse(200, format_string('Feed %name exists.', array('%name' => $feed->title)));
$this->assertRaw("Quote&quot; Amp&amp;");
}
}

View File

@ -5,8 +5,8 @@ version = VERSION
core = 7.x
hidden = TRUE
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<rss version="0.91">
<channel>
<title>Example with Entities</title>
<link>http://example.com</link>
<description>Example RSS Feed With HTML Entities in Title</description>
<language>en-us</language>
<item>
<title>Quote&quot; Amp&amp;</title>
<link>http://example.com/example-turns-one</link>
<description>Some text.</description>
</item>
</channel>
</rss>

View File

@ -87,13 +87,13 @@
* and any value provided can be modified by a user on the block
* configuration screen.
* - pages: (optional) See 'visibility' above. A string that contains one or
* more page paths separated by '\n', '\r', or '\r\n' when 'visibility' is
* set to BLOCK_VISIBILITY_NOTLISTED or BLOCK_VISIBILITY_LISTED, or custom
* PHP code when 'visibility' is set to BLOCK_VISIBILITY_PHP. Paths may use
* '*' as a wildcard (matching any number of characters); '<front>'
* designates the site's front page. For BLOCK_VISIBILITY_PHP, the PHP
* code's return value should be TRUE if the block is to be made visible or
* FALSE if the block should not be visible.
* more page paths separated by "\n", "\r", or "\r\n" when 'visibility' is
* set to BLOCK_VISIBILITY_NOTLISTED or BLOCK_VISIBILITY_LISTED (example:
* "<front>\nnode/1"), or custom PHP code when 'visibility' is set to
* BLOCK_VISIBILITY_PHP. Paths may use '*' as a wildcard (matching any
* number of characters); '<front>' designates the site's front page. For
* BLOCK_VISIBILITY_PHP, the PHP code's return value should be TRUE if the
* block is to be made visible or FALSE if the block should not be visible.
*
* For a detailed usage example, see block_example.module.
*
@ -200,11 +200,13 @@ function hook_block_save($delta = '', $edit = array()) {
* within the module, defined in hook_block_info().
*
* @return
* An array containing the following elements:
* Either an empty array so the block will not be shown or an array containing
* the following elements:
* - subject: The default localized title of the block. If the block does not
* have a default title, this should be set to NULL.
* - content: The content of the block's body. This may be a renderable array
* (preferable) or a string containing rendered HTML content.
* (preferable) or a string containing rendered HTML content. If the content
* is empty the block will not be shown.
*
* For a detailed usage example, see block_example.module.
*
@ -253,8 +255,9 @@ function hook_block_view($delta = '') {
* specific block.
*
* @param $data
* An array of data, as returned from the hook_block_view() implementation of
* the module that defined the block:
* The data as returned from the hook_block_view() implementation of the
* module that defined the block. This could be an empty array or NULL value
* (if the block is empty) or an array containing:
* - subject: The default localized title of the block.
* - content: Either a string or a renderable array representing the content
* of the block. You should check that the content is an array before trying
@ -287,8 +290,9 @@ function hook_block_view_alter(&$data, $block) {
* specific block, rather than implementing hook_block_view_alter().
*
* @param $data
* An array of data, as returned from the hook_block_view() implementation of
* the module that defined the block:
* The data as returned from the hook_block_view() implementation of the
* module that defined the block. This could be an empty array or NULL value
* (if the block is empty) or an array containing:
* - subject: The localized title of the block.
* - content: Either a string or a renderable array representing the content
* of the block. You should check that the content is an array before trying

View File

@ -6,8 +6,8 @@ core = 7.x
files[] = block.test
configure = admin/structure/block
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -401,23 +401,27 @@ function _block_rehash($theme = NULL) {
}
// Save the blocks defined in code for alter context.
$code_blocks = $current_blocks;
$database_blocks = db_select('block', 'b')
$database_blocks = db_select('block', 'b', array('fetch' => PDO::FETCH_ASSOC))
->fields('b')
->condition($or)
->condition('theme', $theme)
->execute();
$original_database_blocks = array();
foreach ($database_blocks as $block) {
// Preserve info which is not in the database.
$block->info = $current_blocks[$block->module][$block->delta]['info'];
$module = $block['module'];
$delta = $block['delta'];
$original_database_blocks[$module][$delta] = $block;
// The cache mode can only by set from hook_block_info(), so that has
// precedence over the database's value.
if (isset($current_blocks[$block->module][$block->delta]['cache'])) {
$block->cache = $current_blocks[$block->module][$block->delta]['cache'];
if (isset($current_blocks[$module][$delta]['cache'])) {
$block['cache'] = $current_blocks[$module][$delta]['cache'];
}
// Preserve info which is not in the database.
$block['info'] = $current_blocks[$module][$delta]['info'];
// Blocks stored in the database override the blocks defined in code.
$current_blocks[$block->module][$block->delta] = get_object_vars($block);
$current_blocks[$module][$delta] = $block;
// Preserve this block.
$bids[$block->bid] = $block->bid;
$bids[$block['bid']] = $block['bid'];
}
drupal_alter('block_info', $current_blocks, $theme, $code_blocks);
foreach ($current_blocks as $module => $module_blocks) {
@ -456,7 +460,15 @@ function _block_rehash($theme = NULL) {
else {
$primary_keys = array();
}
drupal_write_record('block', $block, $primary_keys);
// If the block is new or differs from the original database block, save
// it. To determine whether there was a change it is enough to examine
// the values for the keys in the original database record as that
// contained every database field.
if (!$primary_keys || array_diff_assoc($original_database_blocks[$module][$delta], $block)) {
drupal_write_record('block', $block, $primary_keys);
// Make it possible to test this.
$block['saved'] = TRUE;
}
// Add to the list of blocks we return.
$blocks[] = $block;
}
@ -880,9 +892,11 @@ function _block_render_blocks($region_blocks) {
else {
$array = module_invoke($block->module, 'block_view', $block->delta);
// Valid PHP function names cannot contain hyphens.
$delta = str_replace('-', '_', $block->delta);
// Allow modules to modify the block before it is viewed, via either
// hook_block_view_alter() or hook_block_view_MODULE_DELTA_alter().
drupal_alter(array('block_view', "block_view_{$block->module}_{$block->delta}"), $array, $block);
drupal_alter(array('block_view', "block_view_{$block->module}_{$delta}"), $array, $block);
if (isset($cid)) {
cache_set($cid, $array, 'cache_block', CACHE_TEMPORARY);

View File

@ -193,7 +193,7 @@ class BlockTestCase extends DrupalWebTestCase {
}
/**
* Test block visibility when using "pages" restriction but leaving
* Test block visibility when using "pages" restriction but leaving
* "pages" textarea empty
*/
function testBlockVisibilityListedEmpty() {
@ -752,6 +752,48 @@ class BlockTemplateSuggestionsUnitTest extends DrupalUnitTestCase {
}
}
/**
* Tests for hook_block_view_MODULE_DELTA_alter().
*/
class BlockViewModuleDeltaAlterWebTest extends DrupalWebTestCase {
public static function getInfo() {
return array(
'name' => 'Block view module delta alter',
'description' => 'Test the hook_block_view_MODULE_DELTA_alter() hook.',
'group' => 'Block',
);
}
public function setUp() {
parent::setUp(array('block_test'));
}
/**
* Tests that the alter hook is called, even if the delta contains a hyphen.
*/
public function testBlockViewModuleDeltaAlter() {
$block = new stdClass;
$block->module = 'block_test';
$block->delta = 'test_underscore';
$block->title = '';
$render_array = _block_render_blocks(array('region' => $block));
$render = array_pop($render_array);
$test_underscore = $render->content['#markup'];
$this->assertEqual($test_underscore, 'hook_block_view_MODULE_DELTA_alter', 'Found expected altered block content for delta with underscore');
$block = new stdClass;
$block->module = 'block_test';
$block->delta = 'test-hyphen';
$block->title = '';
$render_array = _block_render_blocks(array('region' => $block));
$render = array_pop($render_array);
$test_hyphen = $render->content['#markup'];
$this->assertEqual($test_hyphen, 'hook_block_view_MODULE_DELTA_alter', 'Hyphens (-) in block delta were replaced by underscore (_)');
}
}
/**
* Tests that hidden regions do not inherit blocks when a theme is enabled.
*/
@ -857,3 +899,81 @@ class BlockInvalidRegionTestCase extends DrupalWebTestCase {
$this->assertNoRaw($warning_message, 'Disabled block in the invalid region will not trigger the warning.');
}
}
/**
* Tests that block rehashing works correctly.
*/
class BlockHashTestCase extends DrupalWebTestCase {
public static function getInfo() {
return array(
'name' => 'Block rehash',
'description' => 'Checks _block_rehash() functionality.',
'group' => 'Block',
);
}
function setUp() {
parent::setUp(array('block'));
}
/**
* Tests that block rehashing does not write to the database too often.
*/
function testBlockRehash() {
// No hook_block_info_alter(), no save.
$this->doRehash();
module_enable(array('block_test'), FALSE);
// Save the new blocks, check that the new blocks exist by checking weight.
_block_rehash();
$this->assertWeight(0);
// Now hook_block_info_alter() exists but no blocks are saved on a second
// rehash.
$this->doRehash();
$this->assertWeight(0);
// Now hook_block_info_alter() exists and is changing one block which
// should be saved.
$GLOBALS['conf']['block_test_info_alter'] = 1;
$this->doRehash(TRUE);
$this->assertWeight(10000);
// Now hook_block_info_alter() exists but already changed the block's
// weight before, so it should not be saved again.
$this->doRehash();
$this->assertWeight(10000);
}
/**
* Performs a block rehash and checks several related assertions.
*
* @param $alter_active
* Set to TRUE if the block_test module's hook_block_info_alter()
* implementation is expected to make a change that results in an existing
* block needing to be resaved to the database. Defaults to FALSE.
*/
function doRehash($alter_active = FALSE) {
$saves = 0;
foreach (_block_rehash() as $block) {
$module = $block['module'];
$delta = $block['delta'];
if ($alter_active && $module == 'block_test' && $delta == 'test_html_id') {
$this->assertFalse(empty($block['saved']), "$module $delta saved");
$saves++;
}
else {
$this->assertTrue(empty($block['saved']), "$module $delta not saved");
}
}
$this->assertEqual($alter_active, $saves);
}
/**
* Asserts that the block_test module's block has a given weight.
*
* @param $weight
* The expected weight.
*/
function assertWeight($weight) {
$db_weight = db_query('SELECT weight FROM {block} WHERE module = :module AND delta = :delta', array(':module' => 'block_test', ':delta' => 'test_html_id'))->fetchField();
// By casting to string the assert fails on FALSE.
$this->assertIdentical((string) $db_weight, (string) $weight);
}
}

View File

@ -5,8 +5,8 @@ version = VERSION
core = 7.x
hidden = TRUE
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -22,6 +22,14 @@ function block_test_block_info() {
'cache' => variable_get('block_test_caching', DRUPAL_CACHE_PER_ROLE),
);
$blocks['test_underscore'] = array(
'info' => t('Test underscore'),
);
$blocks['test-hyphen'] = array(
'info' => t('Test hyphen'),
);
$blocks['test_html_id'] = array(
'info' => t('Test block html id'),
);
@ -34,3 +42,26 @@ function block_test_block_info() {
function block_test_block_view($delta = 0) {
return array('content' => variable_get('block_test_content', ''));
}
/**
* Implements hook_block_view_MODULE_DELTA_alter().
*/
function block_test_block_view_block_test_test_underscore_alter(&$data, $block) {
$data['content'] = 'hook_block_view_MODULE_DELTA_alter';
}
/**
* Implements hook_block_view_MODULE_DELTA_alter().
*/
function block_test_block_view_block_test_test_hyphen_alter(&$data, $block) {
$data['content'] = 'hook_block_view_MODULE_DELTA_alter';
}
/**
* Implements hook_block_info_alter().
*/
function block_test_block_info_alter(&$blocks) {
if (variable_get('block_test_info_alter')) {
$blocks['block_test']['test_html_id']['weight'] = 10000;
}
}

View File

@ -13,8 +13,8 @@ regions[footer] = Footer
regions[highlighted] = Highlighted
regions[help] = Help
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -5,8 +5,8 @@ version = VERSION
core = 7.x
files[] = blog.test
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -42,8 +42,8 @@ class BlogTestCase extends DrupalWebTestCase {
$this->drupalGet('blog/' . $this->big_user->uid);
$this->assertResponse(200);
$this->assertTitle(t("@name's blog", array('@name' => format_username($this->big_user))) . ' | Drupal', t('Blog title was displayed'));
$this->assertText(t('You are not allowed to post a new blog entry.'), t('No new entries can be posted without the right permission'));
$this->assertTitle(t("@name's blog", array('@name' => format_username($this->big_user))) . ' | Drupal', 'Blog title was displayed');
$this->assertText(t('You are not allowed to post a new blog entry.'), 'No new entries can be posted without the right permission');
}
/**
@ -54,8 +54,8 @@ class BlogTestCase extends DrupalWebTestCase {
$this->drupalGet('blog/' . $this->own_user->uid);
$this->assertResponse(200);
$this->assertTitle(t("@name's blog", array('@name' => format_username($this->own_user))) . ' | Drupal', t('Blog title was displayed'));
$this->assertText(t('@author has not created any blog entries.', array('@author' => format_username($this->own_user))), t('Users blog displayed with no entries'));
$this->assertTitle(t("@name's blog", array('@name' => format_username($this->own_user))) . ' | Drupal', 'Blog title was displayed');
$this->assertText(t('@author has not created any blog entries.', array('@author' => format_username($this->own_user))), 'Users blog displayed with no entries');
}
/**
@ -73,7 +73,7 @@ class BlogTestCase extends DrupalWebTestCase {
$edit = array();
$edit['blog_block_count'] = 5;
$this->drupalPost('admin/structure/block/manage/blog/recent/configure', $edit, t('Save block'));
$this->assertEqual(variable_get('blog_block_count', 10), 5, t('Number of recent blog posts changed.'));
$this->assertEqual(variable_get('blog_block_count', 10), 5, 'Number of recent blog posts changed.');
// Do basic tests for each user.
$this->doBasicTests($this->any_user, TRUE);
@ -132,31 +132,31 @@ class BlogTestCase extends DrupalWebTestCase {
$this->drupalGet('admin/help/blog');
$this->assertResponse($response2);
if ($response2 == 200) {
$this->assertTitle(t('Blog | Drupal'), t('Blog help node was displayed'));
$this->assertText(t('Blog'), t('Blog help node was displayed'));
$this->assertTitle(t('Blog | Drupal'), 'Blog help node was displayed');
$this->assertText(t('Blog'), 'Blog help node was displayed');
}
// Verify the blog block was displayed.
$this->drupalGet('');
$this->assertResponse(200);
$this->assertText(t('Recent blog posts'), t('Blog block was displayed'));
$this->assertText(t('Recent blog posts'), 'Blog block was displayed');
// View blog node.
$this->drupalGet('node/' . $node->nid);
$this->assertResponse(200);
$this->assertTitle($node->title . ' | Drupal', t('Blog node was displayed'));
$this->assertTitle($node->title . ' | Drupal', 'Blog node was displayed');
$breadcrumb = array(
l(t('Home'), NULL),
l(t('Blogs'), 'blog'),
l(t("!name's blog", array('!name' => format_username($node_user))), 'blog/' . $node_user->uid),
);
$this->assertRaw(theme('breadcrumb', array('breadcrumb' => $breadcrumb)), t('Breadcrumbs were displayed'));
$this->assertRaw(theme('breadcrumb', array('breadcrumb' => $breadcrumb)), 'Breadcrumbs were displayed');
// View blog edit node.
$this->drupalGet('node/' . $node->nid . '/edit');
$this->assertResponse($response);
if ($response == 200) {
$this->assertTitle('Edit Blog entry ' . $node->title . ' | Drupal', t('Blog edit node was displayed'));
$this->assertTitle('Edit Blog entry ' . $node->title . ' | Drupal', 'Blog edit node was displayed');
}
if ($response == 200) {
@ -166,12 +166,12 @@ class BlogTestCase extends DrupalWebTestCase {
$edit["title"] = 'node/' . $node->nid;
$edit["body[$langcode][0][value]"] = $this->randomName(256);
$this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
$this->assertRaw(t('Blog entry %title has been updated.', array('%title' => $edit["title"])), t('Blog node was edited'));
$this->assertRaw(t('Blog entry %title has been updated.', array('%title' => $edit["title"])), 'Blog node was edited');
// Delete blog node.
$this->drupalPost('node/' . $node->nid . '/delete', array(), t('Delete'));
$this->assertResponse($response);
$this->assertRaw(t('Blog entry %title has been deleted.', array('%title' => $edit["title"])), t('Blog node was deleted'));
$this->assertRaw(t('Blog entry %title has been deleted.', array('%title' => $edit["title"])), 'Blog node was deleted');
}
}
@ -185,29 +185,29 @@ class BlogTestCase extends DrupalWebTestCase {
// Confirm blog entries link exists on the user page.
$this->drupalGet('user/' . $user->uid);
$this->assertResponse(200);
$this->assertText(t('View recent blog entries'), t('View recent blog entries link was displayed'));
$this->assertText(t('View recent blog entries'), 'View recent blog entries link was displayed');
// Confirm the recent blog entries link goes to the user's blog page.
$this->clickLink('View recent blog entries');
$this->assertTitle(t("@name's blog | Drupal", array('@name' => format_username($user))), t('View recent blog entries link target was correct'));
$this->assertTitle(t("@name's blog | Drupal", array('@name' => format_username($user))), 'View recent blog entries link target was correct');
// Confirm a blog page was displayed.
$this->drupalGet('blog');
$this->assertResponse(200);
$this->assertTitle('Blogs | Drupal', t('Blog page was displayed'));
$this->assertText(t('Home'), t('Breadcrumbs were displayed'));
$this->assertTitle('Blogs | Drupal', 'Blog page was displayed');
$this->assertText(t('Home'), 'Breadcrumbs were displayed');
$this->assertLink(t('Create new blog entry'));
// Confirm a blog page was displayed per user.
$this->drupalGet('blog/' . $user->uid);
$this->assertTitle(t("@name's blog | Drupal", array('@name' => format_username($user))), t('User blog node was displayed'));
$this->assertTitle(t("@name's blog | Drupal", array('@name' => format_username($user))), 'User blog node was displayed');
// Confirm a blog feed was displayed.
$this->drupalGet('blog/feed');
$this->assertTitle(t('Drupal blogs'), t('Blog feed was displayed'));
$this->assertTitle(t('Drupal blogs'), 'Blog feed was displayed');
// Confirm a blog feed was displayed per user.
$this->drupalGet('blog/' . $user->uid . '/feed');
$this->assertTitle(t("@name's blog", array('@name' => format_username($user))), t('User blog feed was displayed'));
$this->assertTitle(t("@name's blog", array('@name' => format_username($user))), 'User blog feed was displayed');
}
}

View File

@ -7,8 +7,8 @@ files[] = book.test
configure = admin/content/book/settings
stylesheets[all][] = book.css
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -5,8 +5,8 @@ version = VERSION
core = 7.x
files[] = color.test
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -240,6 +240,7 @@ function color_scheme_form($complete_form, &$form_state, $theme) {
$form['palette'][$name] = array(
'#type' => 'textfield',
'#title' => check_plain($names[$name]),
'#value_callback' => 'color_palette_color_value',
'#default_value' => $value,
'#size' => 8,
);
@ -294,6 +295,52 @@ function theme_color_scheme_form($variables) {
return $output;
}
/**
* Determines the value for a palette color field.
*
* @param $element
* The form element whose value is being populated.
* @param $input
* The incoming input to populate the form element. If this is FALSE,
* the element's default value should be returned.
* @param $form_state
* A keyed array containing the current state of the form.
*
* @return
* The data that will appear in the $form_state['values'] collection for this
* element. Return nothing to use the default.
*/
function color_palette_color_value($element, $input = FALSE, $form_state = array()) {
// If we suspect a possible cross-site request forgery attack, only accept
// hexadecimal CSS color strings from user input, to avoid problems when this
// value is used in the JavaScript preview.
if ($input !== FALSE) {
// Start with the provided value for this textfield, and validate that if
// necessary, falling back on the default value.
$value = form_type_textfield_value($element, $input, $form_state);
if (!$value || !isset($form_state['complete form']['#token']) || color_valid_hexadecimal_string($value) || drupal_valid_token($form_state['values']['form_token'], $form_state['complete form']['#token'])) {
return $value;
}
else {
return $element['#default_value'];
}
}
}
/**
* Determines if a hexadecimal CSS color string is valid.
*
* @param $color
* The string to check.
*
* @return
* TRUE if the string is a valid hexadecimal CSS color string, or FALSE if it
* isn't.
*/
function color_valid_hexadecimal_string($color) {
return preg_match('/^#([a-f0-9]{3}){1,2}$/iD', $color);
}
/**
* Form validation handler for color_scheme_form().
*
@ -302,7 +349,7 @@ function theme_color_scheme_form($variables) {
function color_scheme_form_validate($form, &$form_state) {
// Only accept hexadecimal CSS color strings to avoid XSS upon use.
foreach ($form_state['values']['palette'] as $key => $color) {
if (!preg_match('/^#([a-f0-9]{3}){1,2}$/iD', $color)) {
if (!color_valid_hexadecimal_string($color)) {
form_set_error('palette][' . $key, t('%name must be a valid hexadecimal CSS color value.', array('%name' => $form['color']['palette'][$key]['#title'])));
}
}

View File

@ -9,8 +9,8 @@ files[] = comment.test
configure = admin/content/comment
stylesheets[all][] = comment.css
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -490,7 +490,7 @@ function comment_permalink($cid) {
// Return the node view, this will show the correct comment in context.
return menu_execute_active_handler('node/' . $node->nid, FALSE);
}
drupal_not_found();
return MENU_NOT_FOUND;
}
/**
@ -2304,7 +2304,7 @@ function template_preprocess_comment(&$variables) {
$variables['signature'] = $comment->signature;
$uri = entity_uri('comment', $comment);
$uri['options'] += array('attributes' => array('class' => 'permalink', 'rel' => 'bookmark'));
$uri['options'] += array('attributes' => array('class' => array('permalink'), 'rel' => 'bookmark'));
$variables['title'] = l($comment->subject, $uri['path'], $uri['options']);
$variables['permalink'] = l(t('Permalink'), $uri['path'], $uri['options']);

View File

@ -155,7 +155,7 @@ class CommentHelperCase extends DrupalWebTestCase {
$mode_text = 'required';
break;
}
$this->setCommentSettings('comment_preview', $mode, 'Comment preview ' . $mode_text . '.');
$this->setCommentSettings('comment_preview', $mode, format_string('Comment preview @mode_text.', array('@mode_text' => $mode_text)));
}
/**
@ -175,7 +175,7 @@ class CommentHelperCase extends DrupalWebTestCase {
* Anonymous level.
*/
function setCommentAnonymous($level) {
$this->setCommentSettings('comment_anonymous', $level, 'Anonymous commenting set to level ' . $level . '.');
$this->setCommentSettings('comment_anonymous', $level, format_string('Anonymous commenting set to level @level.', array('@level' => $level)));
}
/**
@ -185,7 +185,7 @@ class CommentHelperCase extends DrupalWebTestCase {
* Comments per page value.
*/
function setCommentsPerPage($number) {
$this->setCommentSettings('comment_default_per_page', $number, 'Number of comments per page set to ' . $number . '.');
$this->setCommentSettings('comment_default_per_page', $number, format_string('Number of comments per page set to @number.', array('@number' => $number)));
}
/**
@ -201,7 +201,7 @@ class CommentHelperCase extends DrupalWebTestCase {
function setCommentSettings($name, $value, $message) {
variable_set($name . '_article', $value);
// Display status message.
$this->assertTrue(TRUE, $message);
$this->pass($message);
}
/**
@ -273,7 +273,7 @@ class CommentInterfaceTest extends CommentHelperCase {
$this->setCommentPreview(DRUPAL_DISABLED);
$this->setCommentForm(TRUE);
$this->setCommentSubject(FALSE);
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, t('Comment paging changed.'));
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Comment paging changed.');
$this->drupalLogout();
// Post comment #1 without subject or preview.
@ -583,7 +583,7 @@ class CommentInterfaceTest extends CommentHelperCase {
$this->setCommentPreview(DRUPAL_DISABLED);
$this->setCommentForm(TRUE);
$this->setCommentSubject(FALSE);
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, t('Comment paging changed.'));
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Comment paging changed.');
$this->drupalLogout();
// Creates a second user to post comments.
@ -954,7 +954,7 @@ class CommentPreviewTest extends CommentHelperCase {
$this->setCommentPreview(DRUPAL_OPTIONAL);
$this->setCommentForm(TRUE);
$this->setCommentSubject(TRUE);
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, t('Comment paging changed.'));
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Comment paging changed.');
$this->drupalLogout();
// Login as web user and add a signature and a user picture.
@ -1000,7 +1000,7 @@ class CommentPreviewTest extends CommentHelperCase {
$this->setCommentPreview(DRUPAL_OPTIONAL);
$this->setCommentForm(TRUE);
$this->setCommentSubject(TRUE);
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, t('Comment paging changed.'));
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Comment paging changed.');
$edit = array();
$edit['subject'] = $this->randomName(8);
@ -1238,7 +1238,7 @@ class CommentPagerTest extends CommentHelperCase {
$comments[] = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE);
$comments[] = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE);
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_FLAT, t('Comment paging changed.'));
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_FLAT, 'Comment paging changed.');
// Set comments to one per page so that we are able to test paging without
// needing to insert large numbers of comments.
@ -1279,7 +1279,7 @@ class CommentPagerTest extends CommentHelperCase {
// If we switch to threaded mode, the replies on the oldest comment
// should be bumped to the first page and comment 6 should be bumped
// to the second page.
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, t('Switched to threaded mode.'));
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Switched to threaded mode.');
$this->drupalGet('node/' . $node->nid, array('query' => array('page' => 0)));
$this->assertTrue($this->commentExists($reply, TRUE), 'In threaded mode, reply appears on page 1.');
$this->assertFalse($this->commentExists($comments[1]), 'In threaded mode, comment 2 has been bumped off of page 1.');
@ -1339,7 +1339,7 @@ class CommentPagerTest extends CommentHelperCase {
// - 2
// - 5
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_FLAT, t('Comment paging changed.'));
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_FLAT, 'Comment paging changed.');
$expected_order = array(
0,
@ -1353,7 +1353,7 @@ class CommentPagerTest extends CommentHelperCase {
$this->drupalGet('node/' . $node->nid);
$this->assertCommentOrder($comments, $expected_order);
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, t('Switched to threaded mode.'));
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Switched to threaded mode.');
$expected_order = array(
0,
@ -1435,7 +1435,7 @@ class CommentPagerTest extends CommentHelperCase {
// - 2
// - 5
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_FLAT, t('Comment paging changed.'));
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_FLAT, 'Comment paging changed.');
$expected_pages = array(
1 => 5, // Page of comment 5
@ -1453,7 +1453,7 @@ class CommentPagerTest extends CommentHelperCase {
$this->assertIdentical($expected_page, $returned_page, format_string('Flat mode, @new replies: expected page @expected, returned page @returned.', array('@new' => $new_replies, '@expected' => $expected_page, '@returned' => $returned_page)));
}
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, t('Switched to threaded mode.'));
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Switched to threaded mode.');
$expected_pages = array(
1 => 5, // Page of comment 5
@ -1509,7 +1509,7 @@ class CommentNodeAccessTest extends CommentHelperCase {
$this->setCommentPreview(DRUPAL_DISABLED);
$this->setCommentForm(TRUE);
$this->setCommentSubject(TRUE);
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, t('Comment paging changed.'));
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Comment paging changed.');
$this->drupalLogout();
// Post comment.
@ -2126,7 +2126,7 @@ class CommentThreadingTestCase extends CommentHelperCase {
$this->setCommentPreview(DRUPAL_DISABLED);
$this->setCommentForm(TRUE);
$this->setCommentSubject(TRUE);
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, t('Comment paging changed.'));
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Comment paging changed.');
$this->drupalLogout();
// Create a node.

View File

@ -6,8 +6,8 @@ core = 7.x
files[] = contact.test
configure = admin/structure/contact
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -5,8 +5,8 @@ version = VERSION
core = 7.x
files[] = contextual.test
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -32,7 +32,7 @@ function hook_dashboard_regions() {
* An array containing all dashboard regions, in the format provided by
* hook_dashboard_regions().
*/
function hook_dashboard_regions_alter($regions) {
function hook_dashboard_regions_alter(&$regions) {
// Remove the sidebar region defined by the core dashboard module.
unset($regions['dashboard_sidebar']);
}

View File

@ -7,8 +7,8 @@ files[] = dashboard.test
dependencies[] = block
configure = admin/dashboard/customize
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -49,15 +49,15 @@ class DashboardBlocksTestCase extends DrupalWebTestCase {
// Ensure admin access.
$this->drupalGet('admin/dashboard');
$this->assertResponse(200, t('Admin has access to the dashboard.'));
$this->assertRaw($custom_block['title'], t('Admin has access to a dashboard block.'));
$this->assertResponse(200, 'Admin has access to the dashboard.');
$this->assertRaw($custom_block['title'], 'Admin has access to a dashboard block.');
// Ensure non-admin access is denied.
$normal_user = $this->drupalCreateUser();
$this->drupalLogin($normal_user);
$this->drupalGet('admin/dashboard');
$this->assertResponse(403, t('Non-admin has no access to the dashboard.'));
$this->assertNoText($custom_block['title'], t('Non-admin has no access to a dashboard block.'));
$this->assertResponse(403, 'Non-admin has no access to the dashboard.');
$this->assertNoText($custom_block['title'], 'Non-admin has no access to a dashboard block.');
}
/**
@ -70,7 +70,7 @@ class DashboardBlocksTestCase extends DrupalWebTestCase {
$this->drupalGet('admin/dashboard/configure');
foreach ($dashboard_regions as $region => $description) {
$elements = $this->xpath('//option[@value=:region]', array(':region' => $region));
$this->assertTrue(!empty($elements), t('%region is an available choice on the dashboard block configuration page.', array('%region' => $region)));
$this->assertTrue(!empty($elements), format_string('%region is an available choice on the dashboard block configuration page.', array('%region' => $region)));
}
// Ensure blocks cannot be placed in dashboard regions on the standard
@ -78,7 +78,7 @@ class DashboardBlocksTestCase extends DrupalWebTestCase {
$this->drupalGet('admin/structure/block');
foreach ($dashboard_regions as $region => $description) {
$elements = $this->xpath('//option[@value=:region]', array(':region' => $region));
$this->assertTrue(empty($elements), t('%region is not an available choice on the block configuration page.', array('%region' => $region)));
$this->assertTrue(empty($elements), format_string('%region is not an available choice on the block configuration page.', array('%region' => $region)));
}
}
@ -94,24 +94,24 @@ class DashboardBlocksTestCase extends DrupalWebTestCase {
$custom_block['regions[stark]'] = 'dashboard_main';
$this->drupalPost('admin/structure/block/add', $custom_block, t('Save block'));
$this->drupalGet('admin/dashboard');
$this->assertRaw($custom_block['title'], t('Block appears on the dashboard.'));
$this->assertRaw($custom_block['title'], 'Block appears on the dashboard.');
$edit = array();
$edit['modules[Core][dashboard][enable]'] = FALSE;
$this->drupalPost('admin/modules', $edit, t('Save configuration'));
$this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.'));
$this->assertNoRaw('assigned to the invalid region', t('Dashboard blocks gracefully disabled.'));
$this->assertText(t('The configuration options have been saved.'), 'Modules status has been updated.');
$this->assertNoRaw('assigned to the invalid region', 'Dashboard blocks gracefully disabled.');
module_list(TRUE);
$this->assertFalse(module_exists('dashboard'), t('Dashboard disabled.'));
$this->assertFalse(module_exists('dashboard'), 'Dashboard disabled.');
$edit['modules[Core][dashboard][enable]'] = 'dashboard';
$this->drupalPost('admin/modules', $edit, t('Save configuration'));
$this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.'));
$this->assertText(t('The configuration options have been saved.'), 'Modules status has been updated.');
module_list(TRUE);
$this->assertTrue(module_exists('dashboard'), t('Dashboard enabled.'));
$this->assertTrue(module_exists('dashboard'), 'Dashboard enabled.');
$this->drupalGet('admin/dashboard');
$this->assertRaw($custom_block['title'], t('Block still appears on the dashboard.'));
$this->assertRaw($custom_block['title'], 'Block still appears on the dashboard.');
}
/**
@ -121,21 +121,21 @@ class DashboardBlocksTestCase extends DrupalWebTestCase {
// Test "Recent comments", which should be available (defined as
// "administrative") but not enabled.
$this->drupalGet('admin/dashboard');
$this->assertNoText(t('Recent comments'), t('"Recent comments" not on dashboard.'));
$this->assertNoText(t('Recent comments'), '"Recent comments" not on dashboard.');
$this->drupalGet('admin/dashboard/drawer');
$this->assertText(t('Recent comments'), t('Drawer of disabled blocks includes a block defined as "administrative".'));
$this->assertNoText(t('Syndicate'), t('Drawer of disabled blocks excludes a block not defined as "administrative".'));
$this->assertText(t('Recent comments'), 'Drawer of disabled blocks includes a block defined as "administrative".');
$this->assertNoText(t('Syndicate'), 'Drawer of disabled blocks excludes a block not defined as "administrative".');
$this->drupalGet('admin/dashboard/configure');
$elements = $this->xpath('//select[@id=:id]//option[@selected="selected"]', array(':id' => 'edit-blocks-comment-recent-region'));
$this->assertTrue($elements[0]['value'] == 'dashboard_inactive', t('A block defined as "administrative" defaults to dashboard_inactive.'));
$this->assertTrue($elements[0]['value'] == 'dashboard_inactive', 'A block defined as "administrative" defaults to dashboard_inactive.');
// Now enable the block on the dashboard.
$values = array();
$values['blocks[comment_recent][region]'] = 'dashboard_main';
$this->drupalPost('admin/dashboard/configure', $values, t('Save blocks'));
$this->drupalGet('admin/dashboard');
$this->assertText(t('Recent comments'), t('"Recent comments" was placed on dashboard.'));
$this->assertText(t('Recent comments'), '"Recent comments" was placed on dashboard.');
$this->drupalGet('admin/dashboard/drawer');
$this->assertNoText(t('Recent comments'), t('Drawer of disabled blocks excludes enabled blocks.'));
$this->assertNoText(t('Recent comments'), 'Drawer of disabled blocks excludes enabled blocks.');
}
}

View File

@ -5,8 +5,8 @@ version = VERSION
core = 7.x
files[] = dblog.test
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -11,7 +11,7 @@
class DBLogTestCase extends DrupalWebTestCase {
/**
* A user with some relevent administrative permissions.
* A user with some relevant administrative permissions.
*
* @var object
*/

View File

@ -1,4 +1,8 @@
<?php
/**
* @file
* Hooks provided by the Field module.
*/
/**
* @addtogroup hooks
@ -37,6 +41,8 @@
* - delete: (optional) String containing markup (normally a link) used as the
* element's 'delete' operation in the administration interface. Only for
* 'form' context.
*
* @ingroup field_types
*/
function hook_field_extra_fields() {
$extra['node']['poll'] = array(
@ -76,6 +82,8 @@ function hook_field_extra_fields() {
* The associative array of 'pseudo-field' components.
*
* @see hook_field_extra_fields()
*
* @ingroup field_types
*/
function hook_field_extra_fields_alter(&$info) {
// Force node title to always be at the top of the list by default.
@ -113,6 +121,9 @@ function hook_field_extra_fields_alter(&$info) {
/**
* Define Field API field types.
*
* Along with this hook, you also need to implement other hooks. See
* @link field_types Field Types API @endlink for more information.
*
* @return
* An array whose keys are field type names and whose values are arrays
* describing the field type, with the following key/value pairs:
@ -199,8 +210,11 @@ function hook_field_info_alter(&$info) {
/**
* Define the Field API schema for a field structure.
*
* This hook MUST be defined in .install for it to be detected during
* installation and upgrade.
* This is invoked when a field is created, in order to obtain the database
* schema from the module that defines the field's type.
*
* This hook must be defined in the module's .install file for it to be detected
* during installation and upgrade.
*
* @param $field
* A field structure.
@ -650,6 +664,8 @@ function hook_field_delete_revision($entity_type, $entity, $field, $instance, $l
* The source entity from which field values are being copied.
* @param $source_langcode
* The source language from which field values are being copied.
*
* @ingroup field_language
*/
function hook_field_prepare_translation($entity_type, $entity, $field, $instance, $langcode, &$items, $source_entity, $source_langcode) {
// If the translating user is not permitted to use the assigned text format,
@ -1244,7 +1260,7 @@ function hook_field_formatter_view($entity_type, $entity, $field, $instance, $la
*/
/**
* @ingroup field_attach
* @addtogroup field_attach
* @{
*/
@ -1306,6 +1322,13 @@ function hook_field_attach_load($entity_type, $entities, $age, $options) {
* This hook is invoked after the field module has performed the operation.
*
* See field_attach_validate() for details and arguments.
*
* @param $entity_type
* The type of $entity; e.g., 'node' or 'user'.
* @param $entity
* The entity with fields to validate.
* @param array $errors
* An associative array of errors keyed by field_name, language, delta.
*/
function hook_field_attach_validate($entity_type, $entity, &$errors) {
// @todo Needs function body.
@ -1510,6 +1533,8 @@ function hook_field_attach_prepare_translation_alter(&$entity, $context) {
* - entity_type: The type of the entity to be displayed.
* - entity: The entity with fields to render.
* - langcode: The language code $entity has to be displayed in.
*
* @ingroup field_language
*/
function hook_field_language_alter(&$display_language, $context) {
// Do not apply core language fallback rules if they are disabled or if Locale
@ -1531,6 +1556,8 @@ function hook_field_language_alter(&$display_language, $context) {
* An associative array containing:
* - entity_type: The type of the entity the field is attached to.
* - field: A field data structure.
*
* @ingroup field_language
*/
function hook_field_available_languages_alter(&$languages, $context) {
// Add an unavailable language.
@ -1581,7 +1608,7 @@ function hook_field_attach_rename_bundle($entity_type, $bundle_old, $bundle_new)
* @param $entity_type
* The type of entity; for example, 'node' or 'user'.
* @param $bundle
* The bundle that was just deleted.
* The name of the bundle that was just deleted.
* @param $instances
* An array of all instances that existed for the bundle before it was
* deleted.
@ -1596,7 +1623,7 @@ function hook_field_attach_delete_bundle($entity_type, $bundle, $instances) {
}
/**
* @} End of "defgroup field_attach".
* @} End of "addtogroup field_attach".
*/
/**
@ -2256,6 +2283,10 @@ function hook_field_storage_pre_update($entity_type, $entity, &$skip_fields) {
}
}
/**
* @} End of "addtogroup field_storage
*/
/**
* Returns the maximum weight for the entity components handled by the module.
*
@ -2269,9 +2300,12 @@ function hook_field_storage_pre_update($entity_type, $entity, &$skip_fields) {
* @param $context
* The context for which the maximum weight is requested. Either 'form', or
* the name of a view mode.
*
* @return
* The maximum weight of the entity's components, or NULL if no components
* were found.
*
* @ingroup field_info
*/
function hook_field_info_max_weight($entity_type, $bundle, $context) {
$weights = array();
@ -2283,6 +2317,11 @@ function hook_field_info_max_weight($entity_type, $bundle, $context) {
return $weights ? max($weights) : NULL;
}
/**
* @addtogroup field_types
* @{
*/
/**
* Alters the display settings of a field before it gets displayed.
*
@ -2349,6 +2388,10 @@ function hook_field_display_ENTITY_TYPE_alter(&$display, $context) {
}
}
/**
* @} End of "addtogroup field_types
*/
/**
* Alters the display settings of pseudo-fields before an entity is displayed.
*
@ -2364,6 +2407,8 @@ function hook_field_display_ENTITY_TYPE_alter(&$display, $context) {
* - entity_type: The entity type; e.g., 'node' or 'user'.
* - bundle: The bundle name.
* - view_mode: The view mode, e.g. 'full', 'teaser'...
*
* @ingroup field_types
*/
function hook_field_extra_fields_display_alter(&$displays, $context) {
if ($context['entity_type'] == 'taxonomy_term' && $context['view_mode'] == 'full') {
@ -2393,6 +2438,8 @@ function hook_field_extra_fields_display_alter(&$displays, $context) {
* - instance: The instance of the field.
*
* @see hook_field_widget_properties_alter()
*
* @ingroup field_widget
*/
function hook_field_widget_properties_ENTITY_TYPE_alter(&$widget, $context) {
// Change a widget's type according to the time of day.
@ -2403,10 +2450,6 @@ function hook_field_widget_properties_ENTITY_TYPE_alter(&$widget, $context) {
}
}
/**
* @} End of "addtogroup field_storage".
*/
/**
* @addtogroup field_crud
* @{
@ -2602,6 +2645,8 @@ function hook_field_purge_instance($instance) {
*
* @param $field
* The field being purged.
*
* @ingroup field_storage
*/
function hook_field_storage_purge_field($field) {
$table_name = _field_sql_storage_tablename($field);
@ -2619,6 +2664,8 @@ function hook_field_storage_purge_field($field) {
*
* @param $instance
* The instance being purged.
*
* @ingroup field_storage
*/
function hook_field_storage_purge_field_instance($instance) {
db_delete('my_module_field_instance_info')
@ -2640,6 +2687,8 @@ function hook_field_storage_purge_field_instance($instance) {
* The (possibly deleted) field whose data is being purged.
* @param $instance
* The deleted field instance whose data is being purged.
*
* @ingroup field_storage
*/
function hook_field_storage_purge($entity_type, $entity, $field, $instance) {
list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
@ -2679,6 +2728,8 @@ function hook_field_storage_purge($entity_type, $entity, $field, $instance) {
*
* @return
* TRUE if the operation is allowed, and FALSE if the operation is denied.
*
* @ingroup field_types
*/
function hook_field_access($op, $field, $entity_type, $entity, $account) {
if ($field['field_name'] == 'field_of_interest' && $op == 'edit') {

View File

@ -976,6 +976,12 @@ function field_attach_insert($entity_type, $entity) {
/**
* Save field data for an existing entity.
*
* When calling this function outside an entity save operation be sure to
* clear caches for the entity:
* @code
* entity_get_controller($entity_type)->resetCache(array($entity_id))
* @endcode
*
* @param $entity_type
* The type of $entity; e.g. 'node' or 'user'.
* @param $entity

View File

@ -11,8 +11,8 @@ dependencies[] = field_sql_storage
required = TRUE
stylesheets[all][] = theme/field.css
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -819,9 +819,9 @@ function field_view_value($entity_type, $entity, $field_name, $item, $display =
*
* This function can be used by third-party modules that need to output an
* isolated field.
* - Do not use inside node (or other entities) templates, use
* - Do not use inside node (or any other entity) templates; use
* render($content[FIELD_NAME]) instead.
* - Do not use to display all fields in an entity, use
* - Do not use to display all fields in an entity; use
* field_attach_prepare_view() and field_attach_view() instead.
* - The field_view_value() function can be used to output a single formatted
* field value, without label or wrapping field markup.

View File

@ -7,8 +7,8 @@ dependencies[] = field
files[] = field_sql_storage.test
required = TRUE
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -7,8 +7,8 @@ dependencies[] = field
dependencies[] = options
files[] = tests/list.test
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -5,8 +5,8 @@ package = Testing
version = VERSION
hidden = TRUE
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -6,8 +6,8 @@ core = 7.x
dependencies[] = field
files[] = number.test
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -6,8 +6,8 @@ core = 7.x
dependencies[] = field
files[] = options.test
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -359,7 +359,7 @@ class OptionsWidgetsTestCase extends FieldTestCase {
// Test the 'None' option.
// Check that the 'none' option has no efect if actual options are selected
// Check that the 'none' option has no effect if actual options are selected
// as well.
$edit = array("card_2[$langcode][]" => array('_none' => '_none', 0 => 0));
$this->drupalPost('test-entity/manage/' . $entity->ftid . '/edit', $edit, t('Save'));

View File

@ -7,8 +7,8 @@ dependencies[] = field
files[] = text.test
required = TRUE
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -6,8 +6,8 @@ files[] = field_test.entity.inc
version = VERSION
hidden = TRUE
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -60,7 +60,7 @@ function field_test_schema() {
'description' => 'The base table for test entities with a bundle key.',
'fields' => array(
'ftid' => array(
'description' => 'The primary indentifier for a test_entity_bundle_key.',
'description' => 'The primary identifier for a test_entity_bundle_key.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
@ -79,7 +79,7 @@ function field_test_schema() {
'description' => 'The base table for test entities with a bundle.',
'fields' => array(
'ftid' => array(
'description' => 'The primary indentifier for a test_entity_bundle.',
'description' => 'The primary identifier for a test_entity_bundle.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,

View File

@ -936,7 +936,7 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund
$field_label_options = array(
'above' => t('Above'),
'inline' => t('Inline'),
'hidden' => t('<Hidden>'),
'hidden' => '<' . t('Hidden') . '>',
);
$extra_visibility_options = array(
'visible' => t('Visible'),
@ -992,7 +992,7 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund
);
$formatter_options = field_ui_formatter_options($field['type']);
$formatter_options['hidden'] = t('<Hidden>');
$formatter_options['hidden'] = '<' . t('Hidden') . '>';
$table[$name]['format'] = array(
'type' => array(
'#type' => 'select',

View File

@ -6,8 +6,8 @@ core = 7.x
dependencies[] = field
files[] = field_ui.test
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -318,7 +318,7 @@ function field_ui_field_attach_create_bundle($entity_type, $bundle) {
}
/**
* Determines the adminstration path for a bundle.
* Determines the administration path for a bundle.
*/
function _field_ui_bundle_admin_path($entity_type, $bundle_name) {
$bundles = field_info_bundles($entity_type);

View File

@ -186,7 +186,7 @@ function file_field_load($entity_type, $entities, $field, $instances, $langcode,
$items[$id][$delta] = NULL;
}
else {
$items[$id][$delta] = array_merge($item, (array) $files[$item['fid']]);
$items[$id][$delta] = array_merge((array) $files[$item['fid']], $item);
}
}
}
@ -215,8 +215,16 @@ function file_field_presave($entity_type, $entity, $field, $instance, $langcode,
// Make sure that each file which will be saved with this object has a
// permanent status, so that it will not be removed when temporary files are
// cleaned up.
foreach ($items as $item) {
foreach ($items as $delta => $item) {
if (empty($item['fid'])) {
unset($items[$delta]);
continue;
}
$file = file_load($item['fid']);
if (empty($file)) {
unset($items[$delta]);
continue;
}
if (!$file->status) {
$file->status = FILE_STATUS_PERMANENT;
file_save($file);
@ -760,7 +768,7 @@ function file_field_widget_submit($form, &$form_state) {
$langcode = $element['#language'];
$parents = $element['#field_parents'];
$submitted_values = drupal_array_get_nested_value($form_state['values'], array_slice($button['#array_parents'], 0, -2));
$submitted_values = drupal_array_get_nested_value($form_state['values'], array_slice($button['#parents'], 0, -2));
foreach ($submitted_values as $delta => $submitted_value) {
if (!$submitted_value['fid']) {
unset($submitted_values[$delta]);
@ -771,7 +779,7 @@ function file_field_widget_submit($form, &$form_state) {
$submitted_values = array_values($submitted_values);
// Update form_state values.
drupal_array_set_nested_value($form_state['values'], array_slice($button['#array_parents'], 0, -2), $submitted_values);
drupal_array_set_nested_value($form_state['values'], array_slice($button['#parents'], 0, -2), $submitted_values);
// Update items.
$field_state = field_form_get_state($parents, $field_name, $langcode, $form_state);

View File

@ -6,8 +6,8 @@ core = 7.x
dependencies[] = field
files[] = tests/file.test
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -83,7 +83,7 @@ Drupal.file = Drupal.file || {
'%filename': this.value.replace('C:\\fakepath\\', ''),
'%extensions': extensionPattern.replace(/\|/g, ', ')
});
$(this).closest('div.form-managed-file').prepend('<div class="messages error file-upload-js-error">' + error + '</div>');
$(this).closest('div.form-managed-file').prepend('<div class="messages error file-upload-js-error" aria-live="polite">' + error + '</div>');
this.value = '';
return false;
}

View File

@ -246,7 +246,7 @@ function file_ajax_upload() {
return array('#type' => 'ajax', '#commands' => $commands);
}
list($form, $form_state) = ajax_get_form();
list($form, $form_state, $form_id, $form_build_id, $commands) = ajax_get_form();
if (!$form) {
// Invalid form_build_id.
@ -284,7 +284,6 @@ function file_ajax_upload() {
$js = drupal_add_js();
$settings = call_user_func_array('array_merge_recursive', $js['settings']['data']);
$commands = array();
$commands[] = ajax_command_replace(NULL, $output, $settings);
return array('#type' => 'ajax', '#commands' => $commands);
}

View File

@ -5,8 +5,8 @@ version = VERSION
core = 7.x
hidden = TRUE
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -7,8 +7,8 @@ files[] = filter.test
required = TRUE
configure = admin/config/content/formats
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -739,8 +739,8 @@ function filter_list_format($format_id) {
* @param $text
* The text to be filtered.
* @param $format_id
* (optional) The format ID of the text to be filtered. If no format is
* assigned, the fallback format will be used. Defaults to NULL.
* (optional) The machine name of the filter format to be used to filter the
* text. Defaults to the fallback format. See filter_fallback_format().
* @param $langcode
* (optional) The language code of the text to be filtered, e.g. 'en' for
* English. This allows filters to be language aware so language specific

View File

@ -9,8 +9,8 @@ files[] = forum.test
configure = admin/structure/forum
stylesheets[all][] = forum.css
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -5,8 +5,8 @@ version = VERSION
core = 7.x
files[] = help.test
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -592,15 +592,15 @@ function image_crop_form($data) {
'#type' => 'radios',
'#title' => t('Anchor'),
'#options' => array(
'left-top' => t('Top') . ' ' . t('Left'),
'center-top' => t('Top') . ' ' . t('Center'),
'right-top' => t('Top') . ' ' . t('Right'),
'left-center' => t('Center') . ' ' . t('Left'),
'left-top' => t('Top left'),
'center-top' => t('Top center'),
'right-top' => t('Top right'),
'left-center' => t('Center left'),
'center-center' => t('Center'),
'right-center' => t('Center') . ' ' . t('Right'),
'left-bottom' => t('Bottom') . ' ' . t('Left'),
'center-bottom' => t('Bottom') . ' ' . t('Center'),
'right-bottom' => t('Bottom') . ' ' . t('Right'),
'right-center' => t('Center right'),
'left-bottom' => t('Bottom left'),
'center-bottom' => t('Bottom center'),
'right-bottom' => t('Bottom right'),
),
'#theme' => 'image_anchor',
'#default_value' => $data['anchor'],

View File

@ -351,7 +351,7 @@ function image_field_widget_form(&$form, &$form_state, $field, $instance, $langc
if ($field['cardinality'] == 1) {
// If there's only one field, return it as delta 0.
if (empty($elements[0]['#default_value']['fid'])) {
$elements[0]['#description'] = theme('file_upload_help', array('description' => $instance['description'], 'upload_validators' => $elements[0]['#upload_validators']));
$elements[0]['#description'] = theme('file_upload_help', array('description' => field_filter_xss($instance['description']), 'upload_validators' => $elements[0]['#upload_validators']));
}
}
else {

View File

@ -7,8 +7,8 @@ dependencies[] = file
files[] = image.test
configure = admin/config/media/image-styles
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -835,7 +835,7 @@ function image_style_deliver($style, $scheme) {
else {
$headers = module_invoke_all('file_download', $image_uri);
if (in_array(-1, $headers) || empty($headers)) {
return drupal_access_denied();
return MENU_ACCESS_DENIED;
}
if (count($headers)) {
foreach ($headers as $name => $value) {
@ -972,7 +972,9 @@ function image_style_flush($style) {
// Delete the style directory in each registered wrapper.
$wrappers = file_get_stream_wrappers(STREAM_WRAPPERS_WRITE_VISIBLE);
foreach ($wrappers as $wrapper => $wrapper_data) {
file_unmanaged_delete_recursive($wrapper . '://styles/' . $style['name']);
if (file_exists($directory = $wrapper . '://styles/' . $style['name'])) {
file_unmanaged_delete_recursive($directory);
}
}
// Let other modules update as necessary on flush.
@ -1010,10 +1012,14 @@ function image_style_flush($style) {
*/
function image_style_url($style_name, $path) {
$uri = image_style_path($style_name, $path);
// The passed-in $path variable can be either a relative path or a full URI.
$original_uri = file_uri_scheme($path) ? file_stream_wrapper_uri_normalize($path) : file_build_uri($path);
// The token query is added even if the 'image_allow_insecure_derivatives'
// variable is TRUE, so that the emitted links remain valid if it is changed
// back to the default FALSE.
$token_query = array(IMAGE_DERIVATIVE_TOKEN => image_style_path_token($style_name, file_stream_wrapper_uri_normalize($path)));
$token_query = array(IMAGE_DERIVATIVE_TOKEN => image_style_path_token($style_name, $original_uri));
// If not using clean URLs, the image derivative callback is only available
// with the query string. If the file does not exist, use url() to ensure

View File

@ -216,10 +216,20 @@ class ImageStylesPathAndUrlTestCase extends DrupalWebTestCase {
}
// Add some extra chars to the token.
$this->drupalGet(str_replace(IMAGE_DERIVATIVE_TOKEN . '=', IMAGE_DERIVATIVE_TOKEN . '=Zo', $generate_url));
$this->assertResponse(403, 'Image was inaccessible at the URL wih an invalid token.');
$this->assertResponse(403, 'Image was inaccessible at the URL with an invalid token.');
// Change the parameter name so the token is missing.
$this->drupalGet(str_replace(IMAGE_DERIVATIVE_TOKEN . '=', 'wrongparam=', $generate_url));
$this->assertResponse(403, 'Image was inaccessible at the URL wih a missing token.');
$this->assertResponse(403, 'Image was inaccessible at the URL with a missing token.');
// Check that the generated URL is the same when we pass in a relative path
// rather than a URI. We need to temporarily switch the default scheme to
// match the desired scheme before testing this, then switch it back to the
// "temporary" scheme used throughout this test afterwards.
variable_set('file_default_scheme', $scheme);
$relative_path = file_uri_target($original_uri);
$generate_url_from_relative_path = image_style_url($this->style_name, $relative_path);
$this->assertEqual($generate_url, $generate_url_from_relative_path, 'Generated URL is the same regardless of whether it came from a relative path or a file URI.');
variable_set('file_default_scheme', 'temporary');
// Fetch the URL that generates the file.
$this->drupalGet($generate_url);
@ -268,7 +278,7 @@ class ImageStylesPathAndUrlTestCase extends DrupalWebTestCase {
elseif ($clean_url) {
// Add some extra chars to the token.
$this->drupalGet(str_replace(IMAGE_DERIVATIVE_TOKEN . '=', IMAGE_DERIVATIVE_TOKEN . '=Zo', $generate_url));
$this->assertResponse(200, 'Existing image was accessible at the URL wih an invalid token.');
$this->assertResponse(200, 'Existing image was accessible at the URL with an invalid token.');
}
// Allow insecure image derivatives to be created for the remainder of this

View File

@ -6,8 +6,8 @@ core = 7.x
files[] = image_module_test.module
hidden = TRUE
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -1242,9 +1242,7 @@ function locale_translate_delete_page($lid) {
if ($source = db_query('SELECT lid, source FROM {locales_source} WHERE lid = :lid', array(':lid' => $lid))->fetchObject()) {
return drupal_get_form('locale_translate_delete_form', $source);
}
else {
return drupal_not_found();
}
return MENU_NOT_FOUND;
}
/**

View File

@ -6,8 +6,8 @@ core = 7.x
files[] = locale.test
configure = admin/config/regional/language
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -1685,7 +1685,7 @@ class LocaleBrowserDetectionTest extends DrupalUnitTestCase {
);
$test_cases = array(
// Equal qvalue for each language, choose the site prefered one.
// Equal qvalue for each language, choose the site preferred one.
'en,en-US,fr-CA,fr,es-MX' => 'en',
'en-US,en,fr-CA,fr,es-MX' => 'en',
'fr,en' => 'en',

View File

@ -5,8 +5,8 @@ package = Testing
version = VERSION
hidden = TRUE
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -512,8 +512,7 @@ function menu_delete_menu_page($menu) {
// System-defined menus may not be deleted.
$system_menus = menu_list_system_menus();
if (isset($system_menus[$menu['menu_name']])) {
drupal_access_denied();
return;
return MENU_ACCESS_DENIED;
}
return drupal_get_form('menu_delete_menu_confirm', $menu);
}
@ -622,8 +621,7 @@ function menu_item_delete_page($item) {
// Links defined via hook_menu may not be deleted. Updated items are an
// exception, as they can be broken.
if ($item['module'] == 'system' && !$item['updated']) {
drupal_access_denied();
return;
return MENU_ACCESS_DENIED;
}
return drupal_get_form('menu_item_delete_form', $item);
}

View File

@ -6,8 +6,8 @@ core = 7.x
files[] = menu.test
configure = admin/structure/menu
; Information added by drupal.org packaging script on 2013-08-08
version = "7.23"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1375928238"
datestamp = "1399522731"

View File

@ -255,11 +255,11 @@ function _node_characters($length) {
*/
function node_type_form_validate($form, &$form_state) {
$type = new stdClass();
$type->type = trim($form_state['values']['type']);
$type->type = $form_state['values']['type'];
$type->name = trim($form_state['values']['name']);
// Work out what the type was before the user submitted this form
$old_type = trim($form_state['values']['old_type']);
$old_type = $form_state['values']['old_type'];
$types = node_type_get_names();
@ -288,7 +288,7 @@ function node_type_form_submit($form, &$form_state) {
$type = node_type_set_defaults();
$type->type = trim($form_state['values']['type']);
$type->type = $form_state['values']['type'];
$type->name = trim($form_state['values']['name']);
$type->orig_type = trim($form_state['values']['orig_type']);
$type->old_type = isset($form_state['values']['old_type']) ? $form_state['values']['old_type'] : $type->type;

View File

@ -471,6 +471,7 @@ function node_admin_nodes() {
$header['operations'] = array('data' => t('Operations'));
$query = db_select('node', 'n')->extend('PagerDefault')->extend('TableSort');
$query->addTag('node_admin_filter');
node_build_filter_query($query);
if (!user_access('bypass node access')) {
@ -695,6 +696,7 @@ function node_multiple_delete_confirm($form, &$form_state, $nodes) {
function node_multiple_delete_confirm_submit($form, &$form_state) {
if ($form_state['values']['confirm']) {
node_delete_multiple(array_keys($form_state['values']['nodes']));
cache_clear_all();
$count = count($form_state['values']['nodes']);
watchdog('content', 'Deleted @count posts.', array('@count' => $count));
drupal_set_message(format_plural($count, 'Deleted 1 post.', 'Deleted @count posts.'));

View File

@ -1033,9 +1033,17 @@ function hook_node_type_delete($info) {
* This hook is invoked only on the module that defines the node's content type
* (use hook_node_delete() to respond to all node deletions).
*
* This hook is invoked from node_delete_multiple() after the node has been
* removed from the node table in the database, before hook_node_delete() is
* invoked, and before field_attach_delete() is called.
* This hook is invoked from node_delete_multiple() before hook_node_delete()
* is invoked and before field_attach_delete() is called.
*
* Note that when this hook is invoked, the changes have not yet been written
* to the database, because a database transaction is still in progress. The
* transaction is not finalized until the delete operation is entirely
* completed and node_delete_multiple() goes out of scope. You should not rely
* on data in the database at this time as it is not updated yet. You should
* also note that any write/update database queries executed from this hook are
* also not committed immediately. Check node_delete_multiple() and
* db_transaction() for more info.
*
* @param $node
* The node that is being deleted.
@ -1063,21 +1071,19 @@ function hook_delete($node) {
* @ingroup node_api_hooks
*/
function hook_prepare($node) {
if ($file = file_check_upload($field_name)) {
$file = file_save_upload($field_name, _image_filename($file->filename, NULL, TRUE));
if ($file) {
if (!image_get_info($file->uri)) {
form_set_error($field_name, t('Uploaded file is not a valid image'));
return;
}
}
else {
$file = file_save_upload($field_name, _image_filename($file->filename, NULL, TRUE));
if ($file) {
if (!image_get_info($file->uri)) {
form_set_error($field_name, t('Uploaded file is not a valid image'));
return;
}
$node->images['_original'] = $file->uri;
_image_build_derivatives($node, TRUE);
$node->new_file = TRUE;
}
else {
return;
}
$node->images['_original'] = $file->uri;
_image_build_derivatives($node, TRUE);
$node->new_file = TRUE;
}
/**

Some files were not shown because too many files have changed in this diff Show More