Commit c3c65075 authored by Riccardo Padovani's avatar Riccardo Padovani

Updated Drupal to version 7.28

parent bcadec9c
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.
......
......@@ -20,18 +20,21 @@ initial database files. Next you must log in and set the access database rights:
Again, you will be asked for the 'username' database password. At the MySQL
prompt, enter the following command:
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER
ON databasename.*
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER,
CREATE TEMPORARY TABLES ON databasename.*
TO 'username'@'localhost' IDENTIFIED BY 'password';
where
where:
'databasename' is the name of your database
'username@localhost' is the username of your MySQL account
'username' is the username of your MySQL account
'localhost' is the web server host where Drupal is installed
'password' is the password required for that username
Note: Unless your database user has all of the privileges listed above, you will
not be able to run Drupal.
Note: Unless the database user/host combination for your Drupal installation
has all of the privileges listed above (except possibly CREATE TEMPORARY TABLES,
which is currently only used by Drupal core automated tests and some
contributed modules), you will not be able to install or run Drupal.
If successful, MySQL will reply with:
......
......@@ -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
----------
......
......@@ -8,7 +8,7 @@
/**
* The current system version.
*/
define('VERSION', '7.27');
define('VERSION', '7.28');
/**
* Core API compatibility.
......
......@@ -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]) : '';
}
}
......@@ -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
......@@ -5067,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
......@@ -5290,8 +5294,15 @@ function drupal_cron_run() {
$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.
......@@ -5946,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) {
......@@ -7827,7 +7840,10 @@ function entity_load_unchanged($entity_type, $id) {
}
/**
* Get the entity controller class for an entity type.
* Gets the entity controller for an entity type.
*
* @return DrupalEntityControllerInterface
* The entity controller object for the specified entity type.
*/
function entity_get_controller($entity_type) {
$controllers = &drupal_static(__FUNCTION__, array());
......
......@@ -28,18 +28,21 @@
* Most Drupal database SELECT queries are performed by a call to db_query() or
* db_query_range(). Module authors should also consider using the PagerDefault
* Extender for queries that return results that need to be presented on
* multiple pages, and the Tablesort Extender for generating appropriate queries
* for sortable tables.
* multiple pages (see https://drupal.org/node/508796), and the TableSort
* Extender for generating appropriate queries for sortable tables
* (see https://drupal.org/node/1848372).
*
* For example, one might wish to return a list of the most recent 10 nodes
* authored by a given user. Instead of directly issuing the SQL query
* @code
* SELECT n.nid, n.title, n.created FROM node n WHERE n.uid = $uid LIMIT 0, 10;
* SELECT n.nid, n.title, n.created FROM node n WHERE n.uid = $uid
* ORDER BY n.created DESC LIMIT 0, 10;
* @endcode
* one would instead call the Drupal functions:
* @code
* $result = db_query_range('SELECT n.nid, n.title, n.created
* FROM {node} n WHERE n.uid = :uid', 0, 10, array(':uid' => $uid));
* FROM {node} n WHERE n.uid = :uid
* ORDER BY n.created DESC', 0, 10, array(':uid' => $uid));
* foreach ($result as $record) {
* // Perform operations on $record->title, etc. here.
* }
......@@ -2380,14 +2383,14 @@ function db_query_range($query, $from, $count, array $args = array(), array $opt
}
/**
* Executes a query string and saves the result set to a temporary table.
* Executes a SELECT query string and saves the result set to a temporary table.
*
* The execution of the query string happens against the active database.
*
* @param $query
* The prepared statement query to run. Although it will accept both named and
* unnamed placeholders, named placeholders are strongly preferred as they are
* more self-documenting.
* The prepared SELECT statement query to run. Although it will accept both
* named and unnamed placeholders, named placeholders are strongly preferred
* as they are more self-documenting.
* @param $args
* An array of values to substitute into the query. If the query uses named
* placeholders, this is an associative array in any order. If the query uses
......
......@@ -90,7 +90,7 @@ class DatabaseConnection_mysql extends DatabaseConnection {
public function queryTemporary($query, array $args = array(), array $options = array()) {
$tablename = $this->generateTemporaryTableName();
$this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE {' . $tablename . '} Engine=MEMORY SELECT', $query), $args, $options);
$this->query('CREATE TEMPORARY TABLE {' . $tablename . '} Engine=MEMORY ' . $query, $args, $options);
return $tablename;
}
......
......@@ -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;
}
......
......@@ -596,7 +596,7 @@ class SelectQueryExtender implements SelectQueryInterface {
public function hasAnyTag() {
$args = func_get_args();
return call_user_func_array(array($this->query, 'hasAnyTags'), $args);
return call_user_func_array(array($this->query, 'hasAnyTag'), $args);
}
public function addMetaData($key, $object) {
......
......@@ -250,7 +250,7 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
$prefixes[$tablename] = '';
$this->setPrefix($prefixes);
$this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE ' . $tablename . ' AS SELECT', $query), $args, $options);
$this->query('CREATE TEMPORARY TABLE ' . $tablename . ' AS ' . $query, $args, $options);
return $tablename;
}
......
......@@ -360,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;
}
}
}
}
......
......@@ -621,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;
}
......@@ -1293,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;
......@@ -1402,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.
......@@ -1414,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.
......@@ -1434,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/features.file-upload.errors.php.
switch ($_FILES['files']['error'][$source]) {
switch ($_FILES['files']['error'][$form_field_name]) {
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_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;
}
......@@ -1480,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'])) {
......@@ -1540,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 .= '/';
......@@ -1549,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;
}
......@@ -1568,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;
}
......@@ -1576,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;
}
......@@ -1597,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;
......
......@@ -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()
*
* @}
*/
......@@ -3101,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
*/
......@@ -4294,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) {
......@@ -4346,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
......@@ -4385,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
......@@ -4402,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
......
......@@ -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'),
......
......@@ -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.
......
......@@ -560,8 +560,8 @@ function drupal_valid_path($path, $dynamic_allowed = FALSE) {
elseif ($dynamic_allowed && preg_match('/\/\%/', $path)) {
// Path is dynamic (ie 'user/%'), so check directly against menu_router table.
if ($item = db_query("SELECT * FROM {menu_router} where path = :path", array(':path' => $path))->fetchAssoc()) {
$item['link_path'] = $form_item['link_path'];
$item['link_title'] = $form_item['link_title'];
$item['link_path'] = $item['path'];
$item['link_title'] = $item['title'];
$item['external'] = FALSE;
$item['options'] = '';
_menu_link_translate($item);
......
......@@ -10,7 +10,7 @@
* @{
* The code registry engine.
*
* Drupal maintains an internal registry of all functions or classes in the
* Drupal maintains an internal registry of all interfaces or classes in the
* system, allowing it to lazy-load code files as needed (reducing the amount
* of code that must be parsed on each request).
*/
......@@ -120,7 +120,10 @@ function registry_get_parsed_files() {
}
/**
* Parse all files that have changed since the registry was last built, and save their function and class listings.
* Parse all changed files and save their interface and class listings.
*
* Parse all files that have changed since the registry was last built, and save
* their interface and class listings.
*
* @param $files
* The list of files to check and parse.
......@@ -149,7 +152,7 @@ function _registry_parse_files($files) {
}
/**
* Parse a file and save its function and class listings.
* Parse a file and save its interface and class listings.
*
* @param $filename
* Name of the file we are going to parse.
......
......@@ -622,7 +622,7 @@ Drupal.ajax.prototype.commands = {
* Command to update a form's build ID.
*/
updateBuildId: function(ajax, response, status) {
$('input[name="form_build_id"][value="' + response.old + '"]').val(response.new);
$('input[name="form_build_id"][value="' + response['old'] + '"]').val(response['new']);
}
};
......
......@@ -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 2014-04-16
version = "7.27"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.28"
project = "drupal"
datestamp = "1397687057"
datestamp = "1399522731"
......@@ -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'));
}
}
/**