From 888c05f9556ebc41e8b55694b7074c37e33e90d9 Mon Sep 17 00:00:00 2001 From: Tim Steiner <tsteiner2@unl.edu> Date: Fri, 5 Aug 2011 15:18:51 +0000 Subject: [PATCH] [gh-195] Merging from testing into staging git-svn-id: file:///tmp/wdn_thm_drupal/branches/drupal-7.x/staging@921 20a16fea-79d4-4915-8869-1ea9d5ebf173 --- CHANGELOG.txt | 23 ++ includes/ajax.inc | 39 +- includes/authorize.inc | 4 +- includes/bootstrap.inc | 125 +++---- includes/common.inc | 7 +- includes/database/mysql/database.inc | 6 +- includes/entity.inc | 105 +++++- includes/errors.inc | 2 + includes/file.inc | 55 ++- includes/form.inc | 13 +- includes/mail.inc | 4 +- includes/menu.inc | 62 +-- includes/password.inc | 2 +- includes/stream_wrappers.inc | 6 +- misc/ajax.js | 9 +- modules/aggregator/aggregator.info | 6 +- modules/aggregator/tests/aggregator_test.info | 6 +- modules/block/block.info | 6 +- modules/block/block.module | 3 +- modules/block/tests/block_test.info | 6 +- modules/blog/blog.info | 6 +- modules/book/book.info | 6 +- modules/book/book.module | 5 + modules/color/color.info | 6 +- modules/comment/comment.info | 6 +- modules/comment/comment.module | 15 +- modules/comment/comment.test | 65 ++++ modules/contact/contact.info | 6 +- modules/contextual/contextual.info | 6 +- modules/dashboard/dashboard.info | 6 +- modules/dblog/dblog.admin.inc | 2 + modules/dblog/dblog.info | 6 +- modules/dblog/dblog.test | 2 + modules/field/field.api.php | 4 +- modules/field/field.form.inc | 4 +- modules/field/field.info | 6 +- .../field_sql_storage/field_sql_storage.info | 6 +- .../field_sql_storage.module | 72 ++-- modules/field/modules/list/list.info | 6 +- modules/field/modules/list/list.module | 2 +- modules/field/modules/list/tests/list.test | 17 + .../field/modules/list/tests/list_test.info | 6 +- modules/field/modules/number/number.info | 6 +- modules/field/modules/options/options.info | 6 +- modules/field/modules/text/text.info | 6 +- modules/field/modules/text/text.test | 6 +- modules/field/tests/field_test.info | 6 +- modules/field_ui/field_ui.admin.inc | 6 +- modules/field_ui/field_ui.info | 6 +- modules/field_ui/field_ui.module | 2 +- modules/field_ui/field_ui.test | 3 +- modules/file/file.info | 6 +- modules/file/file.module | 2 +- modules/file/tests/file.test | 85 ++++- modules/file/tests/file_module_test.info | 6 +- modules/filter/filter.info | 6 +- modules/filter/filter.test | 8 +- modules/forum/forum.info | 6 +- modules/help/help.info | 6 +- modules/image/image.info | 6 +- modules/image/tests/image_module_test.info | 6 +- modules/locale/locale-rtl.css | 12 + modules/locale/locale.css | 6 +- modules/locale/locale.info | 6 +- modules/locale/locale.test | 5 + modules/locale/tests/locale_test.info | 6 +- modules/menu/menu.info | 6 +- modules/menu/menu.install | 52 +++ modules/node/node.api.php | 2 +- modules/node/node.info | 6 +- modules/node/node.install | 5 +- modules/node/node.module | 17 +- modules/node/tests/node_access_test.info | 6 +- modules/node/tests/node_access_test.install | 42 --- modules/node/tests/node_test.info | 6 +- modules/node/tests/node_test_exception.info | 6 +- modules/openid/openid.info | 6 +- modules/openid/tests/openid_test.info | 6 +- modules/overlay/overlay.info | 6 +- modules/path/path.info | 6 +- modules/path/path.test | 3 +- modules/php/php.info | 6 +- modules/poll/poll.info | 6 +- modules/poll/poll.module | 4 + modules/profile/profile.info | 6 +- modules/profile/profile.module | 1 + modules/rdf/rdf.info | 6 +- modules/rdf/tests/rdf_test.info | 6 +- modules/search/search.admin.inc | 4 +- modules/search/search.api.php | 4 + modules/search/search.info | 6 +- .../search/tests/search_embedded_form.info | 6 +- .../search/tests/search_embedded_form.module | 3 +- modules/search/tests/search_extra_type.info | 6 +- modules/shortcut/shortcut.info | 6 +- modules/shortcut/shortcut.install | 7 + modules/simpletest/simpletest.info | 6 +- .../simpletest/tests/actions_loop_test.info | 6 +- modules/simpletest/tests/ajax_forms_test.info | 6 +- modules/simpletest/tests/ajax_test.info | 6 +- modules/simpletest/tests/batch_test.info | 6 +- modules/simpletest/tests/common_test.info | 6 +- modules/simpletest/tests/database_test.info | 6 +- ...drupal_system_listing_compatible_test.info | 6 +- ...upal_system_listing_incompatible_test.info | 6 +- .../simpletest/tests/entity_cache_test.info | 6 +- .../tests/entity_cache_test_dependency.info | 6 +- .../tests/entity_crud_hook_test.info | 6 +- modules/simpletest/tests/entity_query.test | 127 +++++++ modules/simpletest/tests/error_test.info | 6 +- modules/simpletest/tests/file.test | 139 ++++++- modules/simpletest/tests/file_test.info | 6 +- modules/simpletest/tests/file_test.module | 17 + modules/simpletest/tests/filter_test.info | 6 +- modules/simpletest/tests/form_test.info | 6 +- modules/simpletest/tests/image_test.info | 6 +- modules/simpletest/tests/mail.test | 353 ++++++++++++++++++ modules/simpletest/tests/menu.test | 8 + modules/simpletest/tests/menu_test.info | 6 +- modules/simpletest/tests/module_test.info | 6 +- .../simpletest/tests/requirements1_test.info | 6 +- .../simpletest/tests/requirements2_test.info | 6 +- modules/simpletest/tests/session_test.info | 6 +- .../tests/system_dependencies_test.info | 6 +- modules/simpletest/tests/system_test.info | 6 +- modules/simpletest/tests/taxonomy_test.info | 6 +- modules/simpletest/tests/theme_test.info | 6 +- modules/simpletest/tests/update_test_1.info | 6 +- modules/simpletest/tests/update_test_2.info | 6 +- modules/simpletest/tests/update_test_3.info | 6 +- .../tests/upgrade/drupal-6.menu.database.php | 119 ++++++ .../tests/upgrade/upgrade.menu.test | 44 ++- .../tests/upgrade/upgrade.node.test | 5 + .../tests/upgrade/upgrade.taxonomy.test | 6 + modules/simpletest/tests/url_alter_test.info | 6 +- modules/simpletest/tests/xmlrpc_test.info | 6 +- modules/statistics/statistics.info | 6 +- modules/syslog/syslog.info | 6 +- modules/system/image.gd.inc | 2 +- modules/system/system.admin.inc | 2 +- modules/system/system.api.php | 55 ++- modules/system/system.info | 6 +- modules/system/system.install | 3 + modules/system/system.module | 1 + modules/system/system.test | 1 - modules/system/system.tokens.inc | 11 +- modules/taxonomy/taxonomy.admin.inc | 34 +- modules/taxonomy/taxonomy.info | 6 +- modules/taxonomy/taxonomy.install | 1 + modules/taxonomy/taxonomy.pages.inc | 6 +- modules/taxonomy/taxonomy.test | 48 ++- modules/toolbar/toolbar.info | 6 +- modules/tracker/tracker.info | 6 +- .../translation/tests/translation_test.info | 6 +- modules/translation/translation.info | 6 +- modules/translation/translation.test | 13 +- modules/trigger/tests/trigger_test.info | 6 +- modules/trigger/trigger.info | 6 +- modules/update/tests/aaa_update_test.info | 6 +- modules/update/tests/bbb_update_test.info | 6 +- modules/update/tests/ccc_update_test.info | 6 +- modules/update/tests/update_test.info | 6 +- modules/update/update.info | 6 +- modules/user/tests/user_form_test.info | 6 +- modules/user/user-rtl.css | 6 + modules/user/user.admin.inc | 7 +- modules/user/user.css | 4 +- modules/user/user.info | 6 +- modules/user/user.module | 39 +- modules/user/user.permissions.js | 70 +++- profiles/minimal/minimal.info | 6 +- profiles/standard/standard.info | 6 +- profiles/standard/standard.install | 1 - ...drupal_system_listing_compatible_test.info | 6 +- ...upal_system_listing_incompatible_test.info | 6 +- profiles/testing/testing.info | 6 +- scripts/generate-d6-content.sh | 6 +- scripts/run-tests.sh | 150 ++++---- themes/bartik/bartik.info | 6 +- themes/garland/garland.info | 6 +- themes/seven/seven.info | 6 +- themes/stark/stark.info | 6 +- themes/tests/test_theme/test_theme.info | 6 +- .../update_test_basetheme.info | 6 +- .../update_test_subtheme.info | 6 +- 185 files changed, 2086 insertions(+), 772 deletions(-) create mode 100644 modules/locale/locale-rtl.css diff --git a/CHANGELOG.txt b/CHANGELOG.txt index c859f028..33cf9e20 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,4 +1,27 @@ +Drupal 7.7, 2011-07-27 +---------------------- +- Fixed VERSION string. + +Drupal 7.6, 2011-07-27 +---------------------- +- Fixed support for remote streamwrappers. +- AJAX now binds to 'click' instead of 'mousedown'. +- 'Translatable' flag on fields created in UI now defaults to FALSE, to match those created via the API. +- Performance enhancement to permissions page on large numbers of permissions. +- More secure password generation. +- Fix for temporary directory on Windows servers. +- run-tests.sh now uses proc_open() instead of pcntl_fork() for better Windows support. +- Numerous upgrade path fixes. +- Numerous documentation fixes. +- Numerous notice fixes. +- Numerous fixes to improve PHP 5.4 support. +- Numerous RTL improvements. + +Drupal 7.5, 2011-07-27 +---------------------- +- Fixed security issue (Access bypass), see SA-CORE-2011-003. + Drupal 7.4, 2011-06-29 ---------------------- - Rolled back patch that caused fatal errors in CTools, Feeds, and other modules using the class registry. diff --git a/includes/ajax.inc b/includes/ajax.inc index 41c69832..d70808ef 100644 --- a/includes/ajax.inc +++ b/includes/ajax.inc @@ -143,6 +143,21 @@ * - #ajax['event']: The JavaScript event to respond to. This is normally * selected automatically for the type of form widget being used, and * is only needed if you need to override the default behavior. + * - #ajax['prevent']: A JavaScript event to prevent when 'event' is triggered. + * Defaults to 'click' for #ajax on #type 'submit', 'button', and + * 'image_button'. Multiple events may be specified separated by spaces. + * For example, when binding #ajax behaviors to form buttons, pressing the + * ENTER key within a textfield triggers the 'click' event of the form's first + * submit button. Triggering Ajax in this situation leads to problems, like + * breaking autocomplete textfields. Because of that, Ajax behaviors are bound + * to the 'mousedown' event on form buttons by default. However, binding to + * 'mousedown' rather than 'click' means that it is possible to trigger a + * click by pressing the mouse, holding the mouse button down until the Ajax + * request is complete and the button is re-enabled, and then releasing the + * mouse button. For this case, 'prevent' can be set to 'click', so an + * additional event handler is bound to prevent such a click from triggering a + * non-Ajax form submission. This also prevents a textfield's ENTER press + * triggering a button's non-Ajax form submission behavior. * - #ajax['method']: The jQuery method to use to place the new HTML. * Defaults to 'replaceWith'. May be: 'replaceWith', 'append', 'prepend', * 'before', 'after', or 'html'. See the @@ -591,6 +606,7 @@ function ajax_process_form($element, &$form_state) { * An associative array containing the properties of the element. * Properties used: * - #ajax['event'] + * - #ajax['prevent'] * - #ajax['path'] * - #ajax['options'] * - #ajax['wrapper'] @@ -619,13 +635,26 @@ function ajax_pre_render_element($element) { case 'submit': case 'button': case 'image_button': - // Use the mousedown instead of the click event because form - // submission via pressing the enter key triggers a click event on - // submit inputs, inappropriately triggering Ajax behaviors. + // Pressing the ENTER key within a textfield triggers the click event of + // the form's first submit button. Triggering Ajax in this situation + // leads to problems, like breaking autocomplete textfields, so we bind + // to mousedown instead of click. + // @see http://drupal.org/node/216059 $element['#ajax']['event'] = 'mousedown'; - // Attach an additional event handler so that Ajax behaviors - // can be triggered still via keyboard input. + // Retain keyboard accessibility by setting 'keypress'. This causes + // ajax.js to trigger 'event' when SPACE or ENTER are pressed while the + // button has focus. $element['#ajax']['keypress'] = TRUE; + // Binding to mousedown rather than click means that it is possible to + // trigger a click by pressing the mouse, holding the mouse button down + // until the Ajax request is complete and the button is re-enabled, and + // then releasing the mouse button. Set 'prevent' so that ajax.js binds + // an additional handler to prevent such a click from triggering a + // non-Ajax form submission. This also prevents a textfield's ENTER + // press triggering this button's non-Ajax form submission behavior. + if (!isset($element['#ajax']['prevent'])) { + $element['#ajax']['prevent'] = 'click'; + } break; case 'password': diff --git a/includes/authorize.inc b/includes/authorize.inc index 3617d7d0..85286041 100644 --- a/includes/authorize.inc +++ b/includes/authorize.inc @@ -193,7 +193,7 @@ function _authorize_filetransfer_connection_settings_set_defaults(&$element, $ke function authorize_filetransfer_form_validate($form, &$form_state) { // Only validate the form if we have collected all of the user input and are // ready to proceed with updating or installing. - if ($form_state['clicked_button']['#name'] != 'process_updates') { + if ($form_state['triggering_element']['#name'] != 'process_updates') { return; } @@ -224,7 +224,7 @@ function authorize_filetransfer_form_validate($form, &$form_state) { */ function authorize_filetransfer_form_submit($form, &$form_state) { global $base_url; - switch ($form_state['clicked_button']['#name']) { + switch ($form_state['triggering_element']['#name']) { case 'process_updates': // Save the connection settings to the DB. diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index bb07cca4..d6510862 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -8,7 +8,7 @@ /** * The current system version. */ -define('VERSION', '7.4'); +define('VERSION', '7.7'); /** * Core API compatibility. @@ -38,93 +38,69 @@ define('CACHE_PERMANENT', 0); define('CACHE_TEMPORARY', -1); /** - * Log message severity -- Emergency: system is unusable. + * @defgroup logging_severity_levels Logging severity levels + * @{ + * Logging severity levels as defined in RFC 3164. * * The WATCHDOG_* constant definitions correspond to the logging severity levels - * defined in RFC 3164, section 4.1.1: http://www.faqs.org/rfcs/rfc3164.html - * + * defined in RFC 3164, section 4.1.1. PHP supplies predefined LOG_* constants + * for use in the syslog() function, but their values on Windows builds do not + * correspond to RFC 3164. The associated PHP bug report was closed with the + * comment, "And it's also not a bug, as Windows just have less log levels," + * and "So the behavior you're seeing is perfectly normal." + * + * @see http://www.faqs.org/rfcs/rfc3164.html + * @see http://bugs.php.net/bug.php?id=18090 + * @see http://php.net/manual/function.syslog.php + * @see http://php.net/manual/network.constants.php * @see watchdog() * @see watchdog_severity_levels() */ + +/** + * Log message severity -- Emergency: system is unusable. + */ define('WATCHDOG_EMERGENCY', 0); /** * Log message severity -- Alert: action must be taken immediately. - * - * The WATCHDOG_* constant definitions correspond to the logging severity levels - * defined in RFC 3164, section 4.1.1: http://www.faqs.org/rfcs/rfc3164.html - * - * @see watchdog() - * @see watchdog_severity_levels() */ define('WATCHDOG_ALERT', 1); /** * Log message severity -- Critical: critical conditions. - * - * The WATCHDOG_* constant definitions correspond to the logging severity levels - * defined in RFC 3164, section 4.1.1: http://www.faqs.org/rfcs/rfc3164.html - * - * @see watchdog() - * @see watchdog_severity_levels() */ define('WATCHDOG_CRITICAL', 2); /** * Log message severity -- Error: error conditions. - * - * The WATCHDOG_* constant definitions correspond to the logging severity levels - * defined in RFC 3164, section 4.1.1: http://www.faqs.org/rfcs/rfc3164.html - * - * @see watchdog() - * @see watchdog_severity_levels() */ define('WATCHDOG_ERROR', 3); /** * Log message severity -- Warning: warning conditions. - * - * The WATCHDOG_* constant definitions correspond to the logging severity levels - * defined in RFC 3164, section 4.1.1: http://www.faqs.org/rfcs/rfc3164.html - * - * @see watchdog() - * @see watchdog_severity_levels() */ define('WATCHDOG_WARNING', 4); /** * Log message severity -- Notice: normal but significant condition. - * - * The WATCHDOG_* constant definitions correspond to the logging severity levels - * defined in RFC 3164, section 4.1.1: http://www.faqs.org/rfcs/rfc3164.html - * - * @see watchdog() - * @see watchdog_severity_levels() */ define('WATCHDOG_NOTICE', 5); /** * Log message severity -- Informational: informational messages. - * - * The WATCHDOG_* constant definitions correspond to the logging severity levels - * defined in RFC 3164, section 4.1.1: http://www.faqs.org/rfcs/rfc3164.html - * - * @see watchdog() - * @see watchdog_severity_levels() */ define('WATCHDOG_INFO', 6); /** * Log message severity -- Debug: debug-level messages. - * - * The WATCHDOG_* constant definitions correspond to the logging severity levels - * defined in RFC 3164, section 4.1.1: http://www.faqs.org/rfcs/rfc3164.html - * - * @see watchdog() - * @see watchdog_severity_levels() */ define('WATCHDOG_DEBUG', 7); +/** + * @} End of "defgroup logging_severity_levels". + */ + /** * First bootstrap phase: initialize configuration. */ @@ -216,8 +192,11 @@ define('LANGUAGE_RTL', 1); /** * For convenience, define a short form of the request time global. + * + * REQUEST_TIME is a float with microseconds since PHP 5.4.0, but float + * timestamps confuses most of the PHP functions (including date_create()). */ -define('REQUEST_TIME', $_SERVER['REQUEST_TIME']); +define('REQUEST_TIME', (int) $_SERVER['REQUEST_TIME']); /** * Flag for drupal_set_title(); text is not sanitized, so run check_plain(). @@ -311,31 +290,30 @@ function timer_stop($name) { } /** - * Find the appropriate configuration directory. + * Finds the appropriate configuration directory. * - * Try finding a matching configuration directory by stripping the website's + * Finds a matching configuration directory by stripping the website's * hostname from left to right and pathname from right to left. The first - * configuration file found will be used; the remaining will ignored. If no - * configuration file is found, return a default value '$confdir/default'. + * configuration file found will be used and the remaining ones will be ignored. + * If no configuration file is found, return a default value '$confdir/default'. * - * Example for a fictitious site installed at - * http://www.drupal.org:8080/mysite/test/ the 'settings.php' is searched in - * the following directories: + * With a site located at http://www.example.com:8080/mysite/test/, the file, + * settings.php, is searched for in the following directories: * - * 1. $confdir/8080.www.drupal.org.mysite.test - * 2. $confdir/www.drupal.org.mysite.test - * 3. $confdir/drupal.org.mysite.test - * 4. $confdir/org.mysite.test + * 1. $confdir/8080.www.example.com.mysite.test + * 2. $confdir/www.example.com.mysite.test + * 3. $confdir/example.com.mysite.test + * 4. $confdir/com.mysite.test * - * 5. $confdir/8080.www.drupal.org.mysite - * 6. $confdir/www.drupal.org.mysite - * 7. $confdir/drupal.org.mysite - * 8. $confdir/org.mysite + * 5. $confdir/8080.www.example.com.mysite + * 6. $confdir/www.example.com.mysite + * 7. $confdir/example.com.mysite + * 8. $confdir/com.mysite * - * 9. $confdir/8080.www.drupal.org - * 10. $confdir/www.drupal.org - * 11. $confdir/drupal.org - * 12. $confdir/org + * 9. $confdir/8080.www.example.com + * 10. $confdir/www.example.com + * 11. $confdir/example.com + * 12. $confdir/com * * 13. $confdir/default * @@ -343,18 +321,18 @@ function timer_stop($name) { * prior to scanning for directories. It should define an associative array * named $sites, which maps domains to directories. It should be in the form * of: - * + * @code * $sites = array( * 'The url to alias' => 'A directory within the sites directory' * ); - * + * @endcode * For example: - * + * @code * $sites = array( * 'devexample.com' => 'example.com', * 'localhost.example' => 'example.com', * ); - * + * @endcode * The above array will cause Drupal to look for a directory named * "example.com" in the sites directory whenever a request comes from * "example.com", "devexample.com", or "localhost/example". That is useful @@ -363,14 +341,15 @@ function timer_stop($name) { * (files, system table, etc.) this will ensure the paths are correct while * accessed on development servers. * - * @param $require_settings + * @param bool $require_settings * Only configuration directories with an existing settings.php file * will be recognized. Defaults to TRUE. During initial installation, * this is set to FALSE so that Drupal can detect a matching directory, * then create a new settings.php file in it. - * @param reset + * @param bool $reset * Force a full search for matching directories even if one had been - * found previously. + * found previously. Defaults to FALSE. + * * @return * The path of the matching directory. */ diff --git a/includes/common.inc b/includes/common.inc index a3c77ef9..7b0b9e76 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -2258,7 +2258,7 @@ function drupal_http_header_attributes(array $attributes = array()) { * An associative array of key-value pairs to be converted to attributes. * * @return - * A string ready for insertion in a tag. + * A string ready for insertion in a tag (starts with a space). * * @ingroup sanitization */ @@ -2294,7 +2294,9 @@ function drupal_attributes(array $attributes = array()) { * to work in a call to drupal_attributes($options['attributes']). * - 'html' (default FALSE): Whether $text is HTML or just plain-text. For * example, to make an image tag into a link, this must be set to TRUE, or - * you will see the escaped HTML image tag. + * you will see the escaped HTML image tag. $text is not sanitized if + * 'html' is TRUE. The calling function must ensure that $text is already + * safe. * - 'language': An optional language object. If the path being linked to is * internal to the site, $options['language'] is used to determine whether * the link is "active", or pointing to the current page (the language as @@ -7050,6 +7052,7 @@ function drupal_parse_info_format($data) { * Array of the possible severity levels for log messages. * * @see watchdog() + * @ingroup logging_severity_levels */ function watchdog_severity_levels() { return array( diff --git a/includes/database/mysql/database.inc b/includes/database/mysql/database.inc index bc31feaa..157cbfa5 100644 --- a/includes/database/mysql/database.inc +++ b/includes/database/mysql/database.inc @@ -169,10 +169,8 @@ class DatabaseConnection_mysql extends DatabaseConnection { // savepoints which no longer exist. // // To avoid exceptions when no actual error has occurred, we silently - // succeed for PDOExceptions with SQLSTATE 42000 ("Syntax error or - // access rule violation") and MySQL error code 1305 ("SAVEPOINT does - // not exist"). - if ($e->getCode() == '42000' && $e->errorInfo[1] == '1305') { + // succeed for MySQL error code 1305 ("SAVEPOINT does not exist"). + if ($e->errorInfo[1] == '1305') { // If one SAVEPOINT was released automatically, then all were. // Therefore, we keep just the topmost transaction. $this->transactionLayers = array('drupal_transaction'); diff --git a/includes/entity.inc b/includes/entity.inc index 9ee7889c..f363c311 100644 --- a/includes/entity.inc +++ b/includes/entity.inc @@ -457,6 +457,21 @@ class EntityFieldQuery { */ public $fieldConditions = array(); + /** + * List of field meta conditions (language and delta). + * + * Field conditions operate on columns specified by hook_field_schema(), + * the meta conditions operate on columns added by the system: delta + * and language. These can not be mixed with the field conditions because + * field columns can have any name including delta and language. + * + * @var array + * + * @see EntityFieldQuery::fieldLanguageCondition() + * @see EntityFieldQuery::fielDeltaCondition() + */ + public $fieldMetaConditions = array(); + /** * List of property conditions. * @@ -613,6 +628,90 @@ class EntityFieldQuery { /** * Adds a condition on field values. * + * @param $type + * The condition array the given conditions should be added to. + * @param $field + * Either a field name or a field array. + * @param $column + * The column that should hold the value to be matched. + * @param $value + * The value to test the column value against. + * @param $operator + * The operator to be used to test the given value. + * @param $delta_group + * An arbitrary identifier: conditions in the same group must have the same + * $delta_group. + * @param $language_group + * An arbitrary identifier: conditions in the same group must have the same + * $language_group. + * + * @return EntityFieldQuery + * The called object. + * + * @see EntityFieldQuery::addFieldCondition + * @see EntityFieldQuery::deleted + */ + public function fieldCondition($field, $column = NULL, $value = NULL, $operator = NULL, $delta_group = NULL, $language_group = NULL) { + return $this->addFieldCondition($this->fieldConditions, $field, $column, $value, $operator, $delta_group, $language_group); + } + + /** + * Adds a condition on the field language column. + * + * @param $field + * Either a field name or a field array. + * @param $value + * The value to test the column value against. + * @param $operator + * The operator to be used to test the given value. + * @param $delta_group + * An arbitrary identifier: conditions in the same group must have the same + * $delta_group. + * @param $language_group + * An arbitrary identifier: conditions in the same group must have the same + * $language_group. + * + * @return EntityFieldQuery + * The called object. + * + * @see EntityFieldQuery::addFieldCondition + * @see EntityFieldQuery::deleted + */ + public function fieldLanguageCondition($field, $value = NULL, $operator = NULL, $delta_group = NULL, $language_group = NULL) { + return $this->addFieldCondition($this->fieldMetaConditions, $field, 'language', $value, $operator, $delta_group, $language_group); + } + + /** + * Adds a condition on the field delta column. + * + * @param $field + * Either a field name or a field array. + * @param $value + * The value to test the column value against. + * @param $operator + * The operator to be used to test the given value. + * @param $delta_group + * An arbitrary identifier: conditions in the same group must have the same + * $delta_group. + * @param $language_group + * An arbitrary identifier: conditions in the same group must have the same + * $language_group. + * + * @return EntityFieldQuery + * The called object. + * + * @see EntityFieldQuery::addFieldCondition + * @see EntityFieldQuery::deleted + */ + public function fieldDeltaCondition($field, $value = NULL, $operator = NULL, $delta_group = NULL, $language_group = NULL) { + return $this->addFieldCondition($this->fieldMetaConditions, $field, 'delta', $value, $operator, $delta_group, $language_group); + } + + /** + * Adds the given condition to the proper condition array. + * + * @param $conditions + * A reference to an array of conditions. * @param $field * Either a field name or a field array. * @param $column @@ -649,7 +748,7 @@ class EntityFieldQuery { * @return EntityFieldQuery * The called object. */ - public function fieldCondition($field, $column = NULL, $value = NULL, $operator = NULL, $delta_group = NULL, $language_group = NULL) { + protected function addFieldCondition(&$conditions, $field, $column = NULL, $value = NULL, $operator = NULL, $delta_group = NULL, $language_group = NULL) { if (is_scalar($field)) { $field_definition = field_info_field($field); if (empty($field_definition)) { @@ -657,11 +756,11 @@ class EntityFieldQuery { } $field = $field_definition; } - // Ensure the same index is used for fieldConditions as for fields. + // Ensure the same index is used for field conditions as for fields. $index = count($this->fields); $this->fields[$index] = $field; if (isset($column)) { - $this->fieldConditions[$index] = array( + $conditions[$index] = array( 'field' => $field, 'column' => $column, 'value' => $value, diff --git a/includes/errors.inc b/includes/errors.inc index be724285..bd31bebe 100644 --- a/includes/errors.inc +++ b/includes/errors.inc @@ -24,6 +24,8 @@ define('ERROR_REPORTING_DISPLAY_ALL', 2); * Map PHP error constants to watchdog severity levels. * The error constants are documented at * http://php.net/manual/en/errorfunc.constants.php + * + * @ingroup logging_severity_levels */ function drupal_error_levels() { $types = array( diff --git a/includes/file.inc b/includes/file.inc index 73e75cd4..19420ca3 100644 --- a/includes/file.inc +++ b/includes/file.inc @@ -755,7 +755,12 @@ function file_usage_delete(stdClass $file, $module, $type = NULL, $id = NULL, $c */ function file_copy(stdClass $source, $destination = NULL, $replace = FILE_EXISTS_RENAME) { if (!file_valid_uri($destination)) { - watchdog('file', 'File %file (%realpath) could not be copied, because the destination %destination is invalid. This is often caused by improper use of file_copy() or a missing stream wrapper.', array('%file' => $source->uri, '%realpath' => drupal_realpath($source->uri), '%destination' => $destination)); + if (($realpath = drupal_realpath($source->uri)) !== FALSE) { + watchdog('file', 'File %file (%realpath) could not be copied, because the destination %destination is invalid. This is often caused by improper use of file_copy() or a missing stream wrapper.', array('%file' => $source->uri, '%realpath' => $realpath, '%destination' => $destination)); + } + else { + watchdog('file', 'File %file could not be copied, because the destination %destination is invalid. This is often caused by improper use of file_copy() or a missing stream wrapper.', array('%file' => $source->uri, '%destination' => $destination)); + } drupal_set_message(t('The specified file %file could not be copied, because the destination is invalid. More information is available in the system log.', array('%file' => $source->uri)), 'error'); return FALSE; } @@ -847,11 +852,15 @@ function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXIST $original_destination = $destination; // Assert that the source file actually exists. - $source = drupal_realpath($source); if (!file_exists($source)) { // @todo Replace drupal_set_message() calls with exceptions instead. drupal_set_message(t('The specified file %file could not be copied, because no file by that name exists. Please check that you supplied the correct filename.', array('%file' => $original_source)), 'error'); - watchdog('file', 'File %file (%realpath) could not be copied because it does not exist.', array('%file' => $original_source, '%realpath' => drupal_realpath($original_source))); + if (($realpath = drupal_realpath($original_source)) !== FALSE) { + watchdog('file', 'File %file (%realpath) could not be copied because it does not exist.', array('%file' => $original_source, '%realpath' => $realpath)); + } + else { + watchdog('file', 'File %file could not be copied because it does not exist.', array('%file' => $original_source)); + } return FALSE; } @@ -871,7 +880,7 @@ function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXIST $dirname = drupal_dirname($destination); if (!file_prepare_directory($dirname)) { // The destination is not valid. - watchdog('file', 'File %file could not be copied, because the destination directory %destination is not configured correctly.', array('%file' => $original_source, '%destination' => drupal_realpath($dirname))); + watchdog('file', 'File %file could not be copied, because the destination directory %destination is not configured correctly.', array('%file' => $original_source, '%destination' => $dirname)); drupal_set_message(t('The specified file %file could not be copied, because the destination directory is not properly configured. This may be caused by a problem with file or directory permissions. More information is available in the system log.', array('%file' => $original_source)), 'error'); return FALSE; } @@ -881,12 +890,14 @@ function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXIST $destination = file_destination($destination, $replace); if ($destination === FALSE) { drupal_set_message(t('The file %file could not be copied because a file by that name already exists in the destination directory.', array('%file' => $original_source)), 'error'); - watchdog('file', 'File %file could not be copied because a file by that name already exists in the destination directory (%directory)', array('%file' => $original_source, '%destination' => drupal_realpath($destination))); + watchdog('file', 'File %file could not be copied because a file by that name already exists in the destination directory (%directory)', array('%file' => $original_source, '%destination' => $destination)); return FALSE; } // Assert that the source and destination filenames are not the same. - if (drupal_realpath($source) == drupal_realpath($destination)) { + $real_source = drupal_realpath($source); + $real_destination = drupal_realpath($destination); + if ($source == $destination || ($real_source !== FALSE) && ($real_source == $real_destination)) { drupal_set_message(t('The specified file %file was not copied because it would overwrite itself.', array('%file' => $source)), 'error'); watchdog('file', 'File %file could not be copied because it would overwrite itself.', array('%file' => $source)); return FALSE; @@ -895,7 +906,7 @@ function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXIST file_ensure_htaccess(); // Perform the copy operation. if (!@copy($source, $destination)) { - watchdog('file', 'The specified file %file could not be copied to %destination.', array('%file' => $source, '%destination' => drupal_realpath($destination)), WATCHDOG_ERROR); + watchdog('file', 'The specified file %file could not be copied to %destination.', array('%file' => $source, '%destination' => $destination), WATCHDOG_ERR); return FALSE; } @@ -986,7 +997,12 @@ function file_destination($destination, $replace) { */ function file_move(stdClass $source, $destination = NULL, $replace = FILE_EXISTS_RENAME) { if (!file_valid_uri($destination)) { - watchdog('file', 'File %file (%realpath) could not be moved, because the destination %destination is invalid. This may be caused by improper use of file_move() or a missing stream wrapper.', array('%file' => $source->uri, '%realpath' => drupal_realpath($source->uri), '%destination' => $destination)); + if (($realpath = drupal_realpath($source->uri)) !== FALSE) { + watchdog('file', 'File %file (%realpath) could not be moved, because the destination %destination is invalid. This may be caused by improper use of file_move() or a missing stream wrapper.', array('%file' => $source->uri, '%realpath' => $realpath, '%destination' => $destination)); + } + else { + watchdog('file', 'File %file could not be moved, because the destination %destination is invalid. This may be caused by improper use of file_move() or a missing stream wrapper.', array('%file' => $source->uri, '%destination' => $destination)); + } drupal_set_message(t('The specified file %file could not be moved, because the destination is invalid. More information is available in the system log.', array('%file' => $source->uri)), 'error'); return FALSE; } @@ -1212,7 +1228,12 @@ function file_create_filename($basename, $directory) { */ function file_delete(stdClass $file, $force = FALSE) { if (!file_valid_uri($file->uri)) { - watchdog('file', 'File %file (%realpath) could not be deleted because it is not a valid URI. This may be caused by improper use of file_delete() or a missing stream wrapper.', array('%file' => $file->uri, '%realpath' => drupal_realpath($file->uri))); + if (($realpath = drupal_realpath($file->uri)) !== FALSE) { + watchdog('file', 'File %file (%realpath) could not be deleted because it is not a valid URI. This may be caused by improper use of file_delete() or a missing stream wrapper.', array('%file' => $file->uri, '%realpath' => $realpath)); + } + else { + watchdog('file', 'File %file could not be deleted because it is not a valid URI. This may be caused by improper use of file_delete() or a missing stream wrapper.', array('%file' => $file->uri)); + } drupal_set_message(t('The specified file %file could not be deleted, because it is not a valid URI. More information is available in the system log.', array('%file' => $file->uri)), 'error'); return FALSE; } @@ -1256,8 +1277,6 @@ function file_delete(stdClass $file, $force = FALSE) { * @see file_unmanaged_delete_recursive() */ function file_unmanaged_delete($path) { - // Resolve streamwrapper URI to local path. - $path = drupal_realpath($path); if (is_dir($path)) { watchdog('file', '%path is a directory and cannot be removed using file_unmanaged_delete().', array('%path' => $path), WATCHDOG_ERROR); return FALSE; @@ -1299,8 +1318,6 @@ function file_unmanaged_delete($path) { * @see file_unmanaged_delete() */ function file_unmanaged_delete_recursive($path) { - // Resolve streamwrapper URI to local path. - $path = drupal_realpath($path); if (is_dir($path)) { $dir = dir($path); while (($entry = $dir->read()) !== FALSE) { @@ -2331,11 +2348,9 @@ function file_directory_temp() { if (substr(PHP_OS, 0, 3) == 'WIN') { $directories[] = 'c:\\windows\\temp'; $directories[] = 'c:\\winnt\\temp'; - $path_delimiter = '\\'; } else { $directories[] = '/tmp'; - $path_delimiter = '/'; } // PHP may be able to find an alternative tmp directory. // This function exists in PHP 5 >= 5.2.1, but Drupal @@ -2352,8 +2367,14 @@ function file_directory_temp() { } if (empty($temporary_directory)) { - // If no directory has been found default to 'files/tmp' or 'files\\tmp'. - $temporary_directory = variable_get('file_public_path', conf_path() . '/files') . $path_delimiter . 'tmp'; + // If no directory has been found default to 'files/tmp'. + $temporary_directory = variable_get('file_public_path', conf_path() . '/files') . '/tmp'; + + // Windows accepts paths with either slash (/) or backslash (\), but will + // not accept a path which contains both a slash and a backslash. Since + // the 'file_public_path' variable may have either format, we sanitize + // everything to use slash which is supported on all platforms. + $temporary_directory = str_replace('\\', '/', $temporary_directory); } // Save the path of the discovered directory. variable_set('file_temporary_path', $temporary_directory); diff --git a/includes/form.inc b/includes/form.inc index 38ef41cf..8ee0a5a5 100644 --- a/includes/form.inc +++ b/includes/form.inc @@ -272,7 +272,8 @@ function drupal_get_form($form_id) { * form submission may be found in drupal_redirect_form(). * * @return - * The rendered form or NULL, depending upon the $form_state flags that were set. + * The rendered form. This function may also perform a redirect and hence may + * not return at all, depending upon the $form_state flags that were set. * * @see drupal_redirect_form() */ @@ -995,6 +996,8 @@ function drupal_prepare_form($form_id, &$form, &$form_state) { $form += array('#tree' => FALSE, '#parents' => array()); if (!isset($form['#validate'])) { + // Ensure that modules can rely on #validate being set. + $form['#validate'] = array(); // Check for a handler specific to $form_id. if (function_exists($form_id . '_validate')) { $form['#validate'][] = $form_id . '_validate'; @@ -1007,6 +1010,8 @@ function drupal_prepare_form($form_id, &$form, &$form_state) { } if (!isset($form['#submit'])) { + // Ensure that modules can rely on #submit being set. + $form['#submit'] = array(); // Check for a handler specific to $form_id. if (function_exists($form_id . '_submit')) { $form['#submit'][] = $form_id . '_submit'; @@ -2853,9 +2858,9 @@ function form_process_date($element) { /** * Validates the date type to stop dates like February 30, 2006. */ -function date_validate($form) { - if (!checkdate($form['#value']['month'], $form['#value']['day'], $form['#value']['year'])) { - form_error($form, t('The specified date is invalid.')); +function date_validate($element) { + if (!checkdate($element['#value']['month'], $element['#value']['day'], $element['#value']['year'])) { + form_error($element, t('The specified date is invalid.')); } } diff --git a/includes/mail.inc b/includes/mail.inc index d2febed3..7272df97 100644 --- a/includes/mail.inc +++ b/includes/mail.inc @@ -430,7 +430,7 @@ function drupal_html_to_text($string, $allowed_tags = NULL) { $indent[] = count($lists) ? ' "' : '>'; break; case 'li': - $indent[] = is_numeric($lists[0]) ? ' ' . $lists[0]++ . ') ' : ' * '; + $indent[] = isset($lists[0]) && is_numeric($lists[0]) ? ' ' . $lists[0]++ . ') ' : ' * '; break; case 'dd': $indent[] = ' '; @@ -509,7 +509,7 @@ function drupal_html_to_text($string, $allowed_tags = NULL) { $chunk = $casing($chunk); } // Format it and apply the current indentation. - $output .= drupal_wrap_mail($chunk, implode('', $indent)); + $output .= drupal_wrap_mail($chunk, implode('', $indent)) . MAIL_LINE_ENDINGS; // Remove non-quotation markers from indentation. $indent = array_map('_drupal_html_to_text_clean', $indent); } diff --git a/includes/menu.inc b/includes/menu.inc index cfd35c79..5582c452 100644 --- a/includes/menu.inc +++ b/includes/menu.inc @@ -431,6 +431,11 @@ function menu_get_item($path = NULL, $router_item = NULL) { $router_items[$path] = $router_item; } if (!isset($router_items[$path])) { + // Rebuild if we know it's needed, or if the menu masks are missing which + // occurs rarely, likely due to a race condition of multiple rebuilds. + if (variable_get('menu_rebuild_needed', FALSE) || !variable_get('menu_masks', array())) { + menu_rebuild(); + } $original_map = arg(NULL, $path); // Since there is no limit to the length of $path, use a hash to keep it @@ -490,11 +495,6 @@ function menu_execute_active_handler($path = NULL, $deliver = TRUE) { // Only continue if the site status is not set. if ($page_callback_result == MENU_SITE_ONLINE) { - // Rebuild if we know it's needed, or if the menu masks are missing which - // occurs rarely, likely due to a race condition of multiple rebuilds. - if (variable_get('menu_rebuild_needed', FALSE) || !variable_get('menu_masks', array())) { - menu_rebuild(); - } if ($router_item = menu_get_item($path)) { if ($router_item['access']) { if ($router_item['include_file']) { @@ -2696,19 +2696,15 @@ function _menu_navigation_links_rebuild($menu) { } } if ($menu_links) { + // Keep an array of processed menu links, to allow menu_link_save() to + // check this for parents instead of querying the database. + $parent_candidates = array(); // Make sure no child comes before its parent. array_multisort($sort, SORT_NUMERIC, $menu_links); - foreach ($menu_links as $item) { + foreach ($menu_links as $key => $item) { $existing_item = db_select('menu_links') - ->fields('menu_links', array( - 'mlid', - 'menu_name', - 'plid', - 'customized', - 'has_children', - 'updated', - )) + ->fields('menu_links') ->condition('link_path', $item['path']) ->condition('module', 'system') ->execute()->fetchAssoc(); @@ -2727,9 +2723,14 @@ function _menu_navigation_links_rebuild($menu) { $item['has_children'] = $existing_item['has_children']; $item['updated'] = $existing_item['updated']; } - if (!$existing_item || !$existing_item['customized']) { + if ($existing_item && $existing_item['customized']) { + $parent_candidates[$existing_item['mlid']] = $existing_item; + } + else { $item = _menu_link_build($item); - menu_link_save($item); + menu_link_save($item, $existing_item, $parent_candidates); + $parent_candidates[$item['mlid']] = $item; + unset($menu_links[$key]); } } } @@ -2927,12 +2928,17 @@ function _menu_delete_item($item, $force = FALSE) { * to insert a new link. * - plid: (optional) The mlid of the parent. * - router_path: (optional) The path of the relevant router item. + * @param $existing_item + * Optional, the current record from the {menu_links} table as an array. + * @param $parent_candidates + * Optional array of menu links keyed by mlid. Used by + * _menu_navigation_links_rebuild() only. * * @return * The mlid of the saved menu link, or FALSE if the menu link could not be * saved. */ -function menu_link_save(&$item) { +function menu_link_save(&$item, $existing_item = array(), $parent_candidates = array()) { drupal_alter('menu_link', $item); // This is the easiest way to handle the unique internal path '<front>', @@ -2951,15 +2957,20 @@ function menu_link_save(&$item) { 'customized' => 0, 'updated' => 0, ); - $existing_item = FALSE; if (isset($item['mlid'])) { - if ($existing_item = db_query("SELECT * FROM {menu_links} WHERE mlid = :mlid", array(':mlid' => $item['mlid']))->fetchAssoc()) { + if (!$existing_item) { + $existing_item = db_query('SELECT * FROM {menu_links} WHERE mlid = :mlid', array('mlid' => $item['mlid']))->fetchAssoc(); + } + if ($existing_item) { $existing_item['options'] = unserialize($existing_item['options']); } } + else { + $existing_item = FALSE; + } // Try to find a parent link. If found, assign it and derive its menu. - $parent = _menu_link_find_parent($item); + $parent = _menu_link_find_parent($item, $parent_candidates); if (!empty($parent['mlid'])) { $item['plid'] = $parent['mlid']; $item['menu_name'] = $parent['menu_name']; @@ -3093,11 +3104,13 @@ function menu_link_save(&$item) { * * @param $menu_link * A menu link. + * @param $parent_candidates + * An array of menu links keyed by mlid. * @return * A menu link structure of the possible parent or FALSE if no valid parent * has been found. */ -function _menu_link_find_parent($menu_link) { +function _menu_link_find_parent($menu_link, $parent_candidates = array()) { $parent = FALSE; // This item is explicitely top-level, skip the rest of the parenting. @@ -3119,7 +3132,12 @@ function _menu_link_find_parent($menu_link) { } foreach ($candidates as $mlid) { - $parent = db_query("SELECT * FROM {menu_links} WHERE mlid = :mlid", array(':mlid' => $mlid))->fetchAssoc(); + if (isset($parent_candidates[$mlid])) { + $parent = $parent_candidates[$mlid]; + } + else { + $parent = db_query("SELECT * FROM {menu_links} WHERE mlid = :mlid", array(':mlid' => $mlid))->fetchAssoc(); + } if ($parent) { return $parent; } diff --git a/includes/password.inc b/includes/password.inc index 93d34f81..c0761da6 100644 --- a/includes/password.inc +++ b/includes/password.inc @@ -18,7 +18,7 @@ * increase by 1 every Drupal version in order to counteract increases in the * speed and power of computers available to crack the hashes. */ -define('DRUPAL_HASH_COUNT', 14); +define('DRUPAL_HASH_COUNT', 15); /** * The minimum allowed log2 number of iterations for password stretching. diff --git a/includes/stream_wrappers.inc b/includes/stream_wrappers.inc index 7df1f9dc..3c88f3d8 100644 --- a/includes/stream_wrappers.inc +++ b/includes/stream_wrappers.inc @@ -341,7 +341,11 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface * Base implementation of chmod(). */ function chmod($mode) { - return @chmod($this->getLocalPath(), $mode); + $output = @chmod($this->getLocalPath(), $mode); + // We are modifying the underlying file here, so we have to clear the stat + // cache so that PHP understands that URI has changed too. + clearstatcache(); + return $output; } /** diff --git a/misc/ajax.js b/misc/ajax.js index fb03e2b3..830c8aa1 100644 --- a/misc/ajax.js +++ b/misc/ajax.js @@ -182,10 +182,17 @@ Drupal.ajax = function (base, element, element_settings) { // can be triggered through keyboard input as well as e.g. a mousedown // action. if (element_settings.keypress) { - $(element_settings.element).keypress(function (event) { + $(ajax.element).keypress(function (event) { return ajax.keypressResponse(this, event); }); } + + // If necessary, prevent the browser default action of an additional event. + // For example, prevent the browser default action of a click, even if the + // AJAX behavior binds to mousedown. + if (element_settings.prevent) { + $(ajax.element).bind(element_settings.prevent, false); + } }; /** diff --git a/modules/aggregator/aggregator.info b/modules/aggregator/aggregator.info index c0063fe5..c8330219 100644 --- a/modules/aggregator/aggregator.info +++ b/modules/aggregator/aggregator.info @@ -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 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/aggregator/tests/aggregator_test.info b/modules/aggregator/tests/aggregator_test.info index aab1b401..dbbda05b 100644 --- a/modules/aggregator/tests/aggregator_test.info +++ b/modules/aggregator/tests/aggregator_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/block/block.info b/modules/block/block.info index 0c6c4ba6..d6594b49 100644 --- a/modules/block/block.info +++ b/modules/block/block.info @@ -6,8 +6,8 @@ core = 7.x files[] = block.test configure = admin/structure/block -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/block/block.module b/modules/block/block.module index 6b3b23af..b2a3f052 100644 --- a/modules/block/block.module +++ b/modules/block/block.module @@ -612,7 +612,8 @@ function block_theme_initialize($theme) { $has_blocks = (bool) db_query_range('SELECT 1 FROM {block} WHERE theme = :theme', 0, 1, array(':theme' => $theme))->fetchField(); if (!$has_blocks) { $default_theme = variable_get('theme_default', 'bartik'); - $regions = system_region_list($theme); + // Apply only to new theme's visible regions. + $regions = system_region_list($theme, REGIONS_VISIBLE); $result = db_query("SELECT * FROM {block} WHERE theme = :theme", array(':theme' => $default_theme), array('fetch' => PDO::FETCH_ASSOC)); foreach ($result as $block) { // If the region isn't supported by the theme, assign the block to the theme's default region. diff --git a/modules/block/tests/block_test.info b/modules/block/tests/block_test.info index 87df447a..deb41846 100644 --- a/modules/block/tests/block_test.info +++ b/modules/block/tests/block_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/blog/blog.info b/modules/blog/blog.info index c154b86e..a70e7ba0 100644 --- a/modules/blog/blog.info +++ b/modules/blog/blog.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x files[] = blog.test -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/book/book.info b/modules/book/book.info index 15ff031c..08857e37 100644 --- a/modules/book/book.info +++ b/modules/book/book.info @@ -7,8 +7,8 @@ files[] = book.test configure = admin/content/book/settings stylesheets[all][] = book.css -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/book/book.module b/modules/book/book.module index de9561fe..beb17214 100644 --- a/modules/book/book.module +++ b/modules/book/book.module @@ -617,6 +617,8 @@ function _book_update_outline($node) { 'bid' => $node->book['bid'], )) ->execute(); + // Reset the cache of stored books. + drupal_static_reset('book_get_books'); } else { if ($node->book['bid'] != db_query("SELECT bid FROM {book} WHERE nid = :nid", array( @@ -624,6 +626,8 @@ function _book_update_outline($node) { ))->fetchField()) { // Update the bid for this page and all children. book_update_bid($node->book); + // Reset the cache of stored books. + drupal_static_reset('book_get_books'); } } @@ -895,6 +899,7 @@ function book_node_delete($node) { db_delete('book') ->condition('mlid', $node->book['mlid']) ->execute(); + drupal_static_reset('book_get_books'); } } diff --git a/modules/color/color.info b/modules/color/color.info index ee2b2866..bbd87fc1 100644 --- a/modules/color/color.info +++ b/modules/color/color.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x files[] = color.test -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/comment/comment.info b/modules/comment/comment.info index c948e32d..acc4291d 100644 --- a/modules/comment/comment.info +++ b/modules/comment/comment.info @@ -9,8 +9,8 @@ files[] = comment.test configure = admin/content/comment stylesheets[all][] = comment.css -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/comment/comment.module b/modules/comment/comment.module index 8d0c3d36..c17c5a6b 100644 --- a/modules/comment/comment.module +++ b/modules/comment/comment.module @@ -2161,7 +2161,14 @@ function comment_submit($comment) { // 1) Filter it into HTML // 2) Strip out all HTML tags // 3) Convert entities back to plain-text. - $comment->subject = truncate_utf8(trim(decode_entities(strip_tags(check_markup($comment->comment_body[LANGUAGE_NONE][0]['value'], $comment->comment_body[LANGUAGE_NONE][0]['format'])))), 29, TRUE); + $comment_body = $comment->comment_body[LANGUAGE_NONE][0]; + if (isset($comment_body['format'])) { + $comment_text = check_markup($comment_body['value'], $comment_body['format']); + } + else { + $comment_text = check_plain($comment_body['value']); + } + $comment->subject = truncate_utf8(trim(decode_entities(strip_tags($comment_text))), 29, TRUE); // Edge cases where the comment body is populated only by HTML tags will // require a default subject. if ($comment->subject == '') { @@ -2681,6 +2688,10 @@ function comment_rdf_mapping() { */ function comment_file_download_access($field, $entity_type, $entity) { if ($entity_type == 'comment') { - return user_access('access comments') && $entity->status == COMMENT_PUBLISHED || user_access('administer comments'); + if (user_access('access comments') && $entity->status == COMMENT_PUBLISHED || user_access('administer comments')) { + $node = node_load($entity->nid); + return node_access('view', $node); + } + return FALSE; } } diff --git a/modules/comment/comment.test b/modules/comment/comment.test index 770e01d4..c9478f49 100644 --- a/modules/comment/comment.test +++ b/modules/comment/comment.test @@ -251,6 +251,56 @@ class CommentHelperCase extends DrupalWebTestCase { return $match[2]; } + + /** + * Tests new comment marker. + */ + public function testCommentNewCommentsIndicator() { + // Test if the right links are displayed when no comment is present for the + // node. + $this->drupalLogin($this->admin_user); + $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => COMMENT_NODE_OPEN)); + $this->drupalGet('node'); + $this->assertNoLink(t('@count comments', array('@count' => 0))); + $this->assertNoLink(t('@count new comments', array('@count' => 0))); + $this->assertLink(t('Read more')); + $count = $this->xpath('//div[@id=:id]/div[@class=:class]/ul/li', array(':id' => 'node-' . $this->node->nid, ':class' => 'link-wrapper')); + $this->assertTrue(count($count) == 1, t('One child found')); + + // Create a new comment. This helper function may be run with different + // comment settings so use comment_save() to avoid complex setup. + $comment = (object) array( + 'cid' => NULL, + 'nid' => $this->node->nid, + 'node_type' => $this->node->type, + 'pid' => 0, + 'uid' => $this->loggedInUser->uid, + 'status' => COMMENT_PUBLISHED, + 'subject' => $this->randomName(), + 'hostname' => ip_address(), + 'language' => LANGUAGE_NONE, + 'comment_body' => array(LANGUAGE_NONE => array($this->randomName())), + ); + comment_save($comment); + $this->drupalLogout(); + + // Log in with 'web user' and check comment links. + $this->drupalLogin($this->web_user); + $this->drupalGet('node'); + $this->assertLink(t('1 new comment')); + $this->clickLink(t('1 new comment')); + $this->assertRaw('<a id="new"></a>', t('Found "new" marker.')); + $this->assertTrue($this->xpath('//a[@id=:new]/following-sibling::a[1][@id=:comment_id]', array(':new' => 'new', ':comment_id' => 'comment-1')), t('The "new" anchor is positioned at the right comment.')); + + // Test if "new comment" link is correctly removed. + $this->drupalGet('node'); + $this->assertLink(t('1 comment')); + $this->assertLink(t('Read more')); + $this->assertNoLink(t('1 new comment')); + $this->assertNoLink(t('@count new comments', array('@count' => 0))); + $count = $this->xpath('//div[@id=:id]/div[@class=:class]/ul/li', array(':id' => 'node-' . $this->node->nid, ':class' => 'link-wrapper')); + $this->assertTrue(count($count) == 2, print_r($count, TRUE)); + } } class CommentInterfaceTest extends CommentHelperCase { @@ -1912,4 +1962,19 @@ class CommentFieldsTest extends CommentHelperCase { $this->postComment($book_node, $this->randomName(), $this->randomName()); $this->postComment($poll_node, $this->randomName(), $this->randomName()); } + + /** + * Test that comment module works correctly with plain text format. + */ + function testCommentFormat() { + // Disable text processing for comments. + $this->drupalLogin($this->admin_user); + $edit = array('instance[settings][text_processing]' => 0); + $this->drupalPost('admin/structure/types/manage/article/comment/fields/comment_body', $edit, t('Save settings')); + + // Post a comment without an explicit subject. + $this->drupalLogin($this->web_user); + $edit = array('comment_body[und][0][value]' => $this->randomName(8)); + $this->drupalPost('node/' . $this->node->nid, $edit, t('Save')); + } } diff --git a/modules/contact/contact.info b/modules/contact/contact.info index 9a10e285..5f0c59f1 100644 --- a/modules/contact/contact.info +++ b/modules/contact/contact.info @@ -6,8 +6,8 @@ core = 7.x files[] = contact.test configure = admin/structure/contact -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/contextual/contextual.info b/modules/contextual/contextual.info index 65066d79..e059ffa0 100644 --- a/modules/contextual/contextual.info +++ b/modules/contextual/contextual.info @@ -4,8 +4,8 @@ package = Core version = VERSION core = 7.x -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/dashboard/dashboard.info b/modules/dashboard/dashboard.info index b2d2c4d8..e8d7ae67 100644 --- a/modules/dashboard/dashboard.info +++ b/modules/dashboard/dashboard.info @@ -7,8 +7,8 @@ files[] = dashboard.test dependencies[] = block configure = admin/dashboard/customize -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/dblog/dblog.admin.inc b/modules/dblog/dblog.admin.inc index 963e6f8e..0655e756 100644 --- a/modules/dblog/dblog.admin.inc +++ b/modules/dblog/dblog.admin.inc @@ -10,6 +10,8 @@ * * Messages are truncated at 56 chars. Full-length message could be viewed at * the message details page. + * + * @ingroup logging_severity_levels */ function dblog_overview() { $filter = dblog_build_filter_query(); diff --git a/modules/dblog/dblog.info b/modules/dblog/dblog.info index f8c213d6..a369f325 100644 --- a/modules/dblog/dblog.info +++ b/modules/dblog/dblog.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x files[] = dblog.test -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/dblog/dblog.test b/modules/dblog/dblog.test index 5717455e..ca844a36 100644 --- a/modules/dblog/dblog.test +++ b/modules/dblog/dblog.test @@ -528,6 +528,8 @@ class DBLogTestCase extends DrupalWebTestCase { * CSS class attribute. * @return * The watchdog severity constant or NULL if not found. + * + * @ingroup logging_severity_levels */ protected function getSeverityConstant($class) { // Reversed array from dblog_overview(). diff --git a/modules/field/field.api.php b/modules/field/field.api.php index ba44c735..3287dd55 100644 --- a/modules/field/field.api.php +++ b/modules/field/field.api.php @@ -1132,7 +1132,7 @@ function hook_field_attach_form($entity_type, $entity, &$form, &$form_state, $la * * See field_attach_load() for details and arguments. */ -function hook_field_attach_load($entity_type, &$entities, $age, $options) { +function hook_field_attach_load($entity_type, $entities, $age, $options) { // @todo Needs function body. } @@ -1580,7 +1580,7 @@ function hook_field_storage_details_alter(&$details, $field) { * non-deleted fields. If unset or FALSE, only non-deleted fields should be * loaded. */ -function hook_field_storage_load($entity_type, &$entities, $age, $fields, $options) { +function hook_field_storage_load($entity_type, $entities, $age, $fields, $options) { $field_info = field_info_field_by_ids(); $load_current = $age == FIELD_LOAD_CURRENT; diff --git a/modules/field/field.form.inc b/modules/field/field.form.inc index 845f0410..66d93e96 100644 --- a/modules/field/field.form.inc +++ b/modules/field/field.form.inc @@ -373,7 +373,7 @@ function field_default_form_errors($entity_type, $entity, $field, $instance, $la * to return just the changed part of the form. */ function field_add_more_submit($form, &$form_state) { - $button = $form_state['clicked_button']; + $button = $form_state['triggering_element']; // Go one level up in the form, to the widgets container. $element = drupal_array_get_nested_value($form, array_slice($button['#array_parents'], 0, -1)); @@ -398,7 +398,7 @@ function field_add_more_submit($form, &$form_state) { * @see field_add_more_submit() */ function field_add_more_js($form, $form_state) { - $button = $form_state['clicked_button']; + $button = $form_state['triggering_element']; // Go one level up in the form, to the widgets container. $element = drupal_array_get_nested_value($form, array_slice($button['#array_parents'], 0, -1)); diff --git a/modules/field/field.info b/modules/field/field.info index a0008888..661d1841 100644 --- a/modules/field/field.info +++ b/modules/field/field.info @@ -10,8 +10,8 @@ dependencies[] = field_sql_storage required = TRUE stylesheets[all][] = theme/field.css -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/field/modules/field_sql_storage/field_sql_storage.info b/modules/field/modules/field_sql_storage/field_sql_storage.info index 48e9c59c..95e8bb71 100644 --- a/modules/field/modules/field_sql_storage/field_sql_storage.info +++ b/modules/field/modules/field_sql_storage/field_sql_storage.info @@ -7,8 +7,8 @@ dependencies[] = field files[] = field_sql_storage.test required = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/field/modules/field_sql_storage/field_sql_storage.module b/modules/field/modules/field_sql_storage/field_sql_storage.module index 6f49167e..10bae64b 100644 --- a/modules/field/modules/field_sql_storage/field_sql_storage.module +++ b/modules/field/modules/field_sql_storage/field_sql_storage.module @@ -468,7 +468,6 @@ function field_sql_storage_field_storage_purge($entity_type, $entity, $field, $i * Implements hook_field_storage_query(). */ function field_sql_storage_field_storage_query(EntityFieldQuery $query) { - $groups = array(); if ($query->age == FIELD_LOAD_CURRENT) { $tablename_function = '_field_sql_storage_tablename'; $id_key = 'entity_id'; @@ -499,26 +498,12 @@ function field_sql_storage_field_storage_query(EntityFieldQuery $query) { } } - // Add field conditions. - foreach ($query->fieldConditions as $key => $condition) { - $table_alias = $table_aliases[$key]; - $field = $condition['field']; - // Add the specified condition. - $sql_field = "$table_alias." . _field_sql_storage_columnname($field['field_name'], $condition['column']); - $query->addCondition($select_query, $sql_field, $condition); - // Add delta / language group conditions. - foreach (array('delta', 'language') as $column) { - if (isset($condition[$column . '_group'])) { - $group_name = $condition[$column . '_group']; - if (!isset($groups[$column][$group_name])) { - $groups[$column][$group_name] = $table_alias; - } - else { - $select_query->where("$table_alias.$column = " . $groups[$column][$group_name] . ".$column"); - } - } - } - } + // Add field conditions. We need a fresh grouping cache. + drupal_static_reset('_field_sql_storage_query_field_conditions'); + _field_sql_storage_query_field_conditions($query, $select_query, $query->fieldConditions, $table_aliases, '_field_sql_storage_columnname'); + + // Add field meta conditions. + _field_sql_storage_query_field_conditions($query, $select_query, $query->fieldMetaConditions, $table_aliases, '_field_sql_storage_query_columnname'); if (isset($query->deleted)) { $select_query->condition("$field_base_table.deleted", (int) $query->deleted); @@ -591,6 +576,51 @@ function _field_sql_storage_query_join_entity(SelectQuery $select_query, $entity return $entity_base_table; } +/** + * Adds field (meta) conditions to the given query objects respecting groupings. + * + * @param EntityFieldQuery $query + * The field query object to be processed. + * @param SelectQuery $select_query + * The SelectQuery that should get grouping conditions. + * @param condtions + * The conditions to be added. + * @param $table_aliases + * An associative array of table aliases keyed by field index. + * @param $column_callback + * A callback that should return the column name to be used for the field + * conditions. Accepts a field name and a field column name as parameters. + */ +function _field_sql_storage_query_field_conditions(EntityFieldQuery $query, SelectQuery $select_query, $conditions, $table_aliases, $column_callback) { + $groups = &drupal_static(__FUNCTION__, array()); + foreach ($conditions as $key => $condition) { + $table_alias = $table_aliases[$key]; + $field = $condition['field']; + // Add the specified condition. + $sql_field = "$table_alias." . $column_callback($field['field_name'], $condition['column']); + $query->addCondition($select_query, $sql_field, $condition); + // Add delta / language group conditions. + foreach (array('delta', 'language') as $column) { + if (isset($condition[$column . '_group'])) { + $group_name = $condition[$column . '_group']; + if (!isset($groups[$column][$group_name])) { + $groups[$column][$group_name] = $table_alias; + } + else { + $select_query->where("$table_alias.$column = " . $groups[$column][$group_name] . ".$column"); + } + } + } + } +} + +/** + * Field meta condition column callback. + */ +function _field_sql_storage_query_columnname($field_name, $column) { + return $column; +} + /** * Implements hook_field_storage_delete_revision(). * diff --git a/modules/field/modules/list/list.info b/modules/field/modules/list/list.info index 6d3a1f71..2905a0a1 100644 --- a/modules/field/modules/list/list.info +++ b/modules/field/modules/list/list.info @@ -7,8 +7,8 @@ dependencies[] = field dependencies[] = options files[] = tests/list.test -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/field/modules/list/list.module b/modules/field/modules/list/list.module index 608679bb..2518ebcf 100644 --- a/modules/field/modules/list/list.module +++ b/modules/field/modules/list/list.module @@ -343,7 +343,7 @@ function list_allowed_values_string($values) { function list_field_update_forbid($field, $prior_field, $has_data) { if ($field['module'] == 'list' && $has_data) { // Forbid any update that removes allowed values with actual data. - $lost_keys = array_diff(array_keys($field['settings']['allowed_values']), array_keys($prior_field['settings']['allowed_values'])); + $lost_keys = array_diff(array_keys($prior_field['settings']['allowed_values']), array_keys($field['settings']['allowed_values'])); if (_list_values_in_use($field, $lost_keys)) { throw new FieldUpdateForbiddenException(t('Cannot update a list field to not include keys with existing data.')); } diff --git a/modules/field/modules/list/tests/list.test b/modules/field/modules/list/tests/list.test index 941d2b4c..dec09560 100644 --- a/modules/field/modules/list/tests/list.test +++ b/modules/field/modules/list/tests/list.test @@ -55,6 +55,23 @@ class ListFieldTestCase extends FieldTestCase { $this->assertTrue(!empty($form[$this->field_name][$langcode][2]), t('Option 2 exists')); $this->assertTrue(!empty($form[$this->field_name][$langcode][3]), t('Option 3 exists')); + // Use one of the values in an actual entity, and check that this value + // cannot be removed from the list. + $entity = field_test_create_stub_entity(); + $entity->{$this->field_name}[$langcode][0] = array('value' => 1); + field_test_entity_save($entity); + $this->field['settings']['allowed_values'] = array(2 => 'Two'); + try { + field_update_field($this->field); + $this->fail(t('Cannot update a list field to not include keys with existing data.')); + } + catch (FieldException $e) { + $this->pass(t('Cannot update a list field to not include keys with existing data.')); + } + // Empty the value, so that we can actually remove the option. + $entity->{$this->field_name}[$langcode] = array(); + field_test_entity_save($entity); + // Removed options do not appear. $this->field['settings']['allowed_values'] = array(2 => 'Two'); field_update_field($this->field); diff --git a/modules/field/modules/list/tests/list_test.info b/modules/field/modules/list/tests/list_test.info index 69ab5276..52d03ff3 100644 --- a/modules/field/modules/list/tests/list_test.info +++ b/modules/field/modules/list/tests/list_test.info @@ -5,8 +5,8 @@ package = Testing version = VERSION hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/field/modules/number/number.info b/modules/field/modules/number/number.info index 608bcdaf..24801033 100644 --- a/modules/field/modules/number/number.info +++ b/modules/field/modules/number/number.info @@ -6,8 +6,8 @@ core = 7.x dependencies[] = field files[] = number.test -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/field/modules/options/options.info b/modules/field/modules/options/options.info index 84a8351e..fa1b32f3 100644 --- a/modules/field/modules/options/options.info +++ b/modules/field/modules/options/options.info @@ -6,8 +6,8 @@ core = 7.x dependencies[] = field files[] = options.test -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/field/modules/text/text.info b/modules/field/modules/text/text.info index 518cf934..ce426a0c 100644 --- a/modules/field/modules/text/text.info +++ b/modules/field/modules/text/text.info @@ -7,8 +7,8 @@ dependencies[] = field files[] = text.test required = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/field/modules/text/text.test b/modules/field/modules/text/text.test index b42fed7e..59369370 100644 --- a/modules/field/modules/text/text.test +++ b/modules/field/modules/text/text.test @@ -464,7 +464,7 @@ class TextTranslationTestCase extends DrupalWebTestCase { $node = $this->drupalGetNodeByTitle($edit['title']); $this->drupalGet("node/$node->nid/translate"); $this->clickLink(t('add translation')); - $this->assertFieldByXPath("//textarea[@name='body[fr][0][value]']", $body, t('The textfield widget is populated.')); + $this->assertFieldByXPath("//textarea[@name='body[$langcode][0][value]']", $body, t('The textfield widget is populated.')); } /** @@ -484,17 +484,17 @@ class TextTranslationTestCase extends DrupalWebTestCase { ); // Create an article with the first body input format set to "Full HTML". - $langcode = 'en'; $title = $this->randomName(); $edit = array( 'title' => $title, - 'language' => $langcode, + 'language' => 'en', ); $this->drupalPost('node/add/article', $edit, t('Save')); // Populate the body field: the first item gets the "Full HTML" input // format, the second one "Filtered HTML". $formats = array('full_html', 'filtered_html'); + $langcode = LANGUAGE_NONE; foreach ($body as $delta => $value) { $edit = array( "body[$langcode][$delta][value]" => $value, diff --git a/modules/field/tests/field_test.info b/modules/field/tests/field_test.info index dc1b41c9..349814ae 100644 --- a/modules/field/tests/field_test.info +++ b/modules/field/tests/field_test.info @@ -6,8 +6,8 @@ files[] = field_test.entity.inc version = VERSION hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/field_ui/field_ui.admin.inc b/modules/field_ui/field_ui.admin.inc index 96beb133..b594faca 100644 --- a/modules/field_ui/field_ui.admin.inc +++ b/modules/field_ui/field_ui.admin.inc @@ -509,6 +509,10 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle '#cell_attributes' => array('colspan' => 3), '#prefix' => '<div class="add-new-placeholder"> </div>', ), + 'translatable' => array( + '#type' => 'value', + '#value' => FALSE, + ), ); } @@ -753,7 +757,7 @@ function field_ui_field_overview_form_submit($form, &$form_state) { $field = array( 'field_name' => $values['field_name'], 'type' => $values['type'], - 'translatable' => TRUE, + 'translatable' => $values['translatable'], ); $instance = array( 'field_name' => $field['field_name'], diff --git a/modules/field_ui/field_ui.info b/modules/field_ui/field_ui.info index e84d8eed..bf5f535e 100644 --- a/modules/field_ui/field_ui.info +++ b/modules/field_ui/field_ui.info @@ -6,8 +6,8 @@ core = 7.x dependencies[] = field files[] = field_ui.test -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/field_ui/field_ui.module b/modules/field_ui/field_ui.module index 7355e879..27ef3c2d 100644 --- a/modules/field_ui/field_ui.module +++ b/modules/field_ui/field_ui.module @@ -358,7 +358,7 @@ function field_ui_form_node_type_form_alter(&$form, $form_state) { * Redirect to manage fields form. */ function field_ui_form_node_type_form_submit($form, &$form_state) { - if ($form_state['clicked_button']['#parents'][0] === 'save_continue') { + if ($form_state['triggering_element']['#parents'][0] === 'save_continue') { $form_state['redirect'] = _field_ui_bundle_admin_path('node', $form_state['values']['type']) .'/fields'; } } diff --git a/modules/field_ui/field_ui.test b/modules/field_ui/field_ui.test index 5d2ff9bf..9ff6c172 100644 --- a/modules/field_ui/field_ui.test +++ b/modules/field_ui/field_ui.test @@ -613,7 +613,8 @@ class FieldUIManageDisplayTestCase extends FieldUITestCase { // Render a cloned node, so that we do not alter the original. $clone = clone $node; - $output = drupal_render(node_view($clone, $view_mode)); + $element = node_view($clone, $view_mode); + $output = drupal_render($element); $this->verbose(t('Rendered node - view mode: @view_mode', array('@view_mode' => $view_mode)) . '<hr />'. $output); // Assign content so that DrupalWebTestCase functions can be used. diff --git a/modules/file/file.info b/modules/file/file.info index b3a1dc0b..d91af6a1 100644 --- a/modules/file/file.info +++ b/modules/file/file.info @@ -6,8 +6,8 @@ core = 7.x dependencies[] = field files[] = tests/file.test -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/file/file.module b/modules/file/file.module index 3e452511..83de0f62 100644 --- a/modules/file/file.module +++ b/modules/file/file.module @@ -533,7 +533,7 @@ function file_managed_file_validate(&$element, &$form_state) { // If referencing an existing file, only allow if there are existing // references. This prevents unmanaged files from being deleted if this // item were to be deleted. - $clicked_button = end($form_state['clicked_button']['#parents']); + $clicked_button = end($form_state['triggering_element']['#parents']); if ($clicked_button != 'remove_button' && !empty($element['fid']['#value'])) { if ($file = file_load($element['fid']['#value'])) { if ($file->status == FILE_STATUS_PERMANENT) { diff --git a/modules/file/tests/file.test b/modules/file/tests/file.test index ea8c5c67..0e5f97d8 100644 --- a/modules/file/tests/file.test +++ b/modules/file/tests/file.test @@ -12,7 +12,16 @@ class FileFieldTestCase extends DrupalWebTestCase { protected $admin_user; function setUp() { - parent::setUp('file', 'file_module_test'); + // Since this is a base class for many test cases, support the same + // flexibility that DrupalWebTestCase::setUp() has for the modules to be + // passed in as either an array or a variable number of string arguments. + $modules = func_get_args(); + if (isset($modules[0]) && is_array($modules[0])) { + $modules = $modules[0]; + } + $modules[] = 'file'; + $modules[] = 'file_module_test'; + parent::setUp($modules); $this->admin_user = $this->drupalCreateUser(array('access content', 'access administration pages', 'administer site configuration', 'administer users', 'administer permissions', 'administer content types', 'administer nodes', 'bypass node access')); $this->drupalLogin($this->admin_user); } @@ -112,7 +121,7 @@ class FileFieldTestCase extends DrupalWebTestCase { /** * Upload a file to a node. */ - function uploadNodeFile($file, $field_name, $nid_or_type, $new_revision = TRUE) { + function uploadNodeFile($file, $field_name, $nid_or_type, $new_revision = TRUE, $extras = array()) { $langcode = LANGUAGE_NONE; $edit = array( "title" => $this->randomName(), @@ -124,7 +133,8 @@ class FileFieldTestCase extends DrupalWebTestCase { } else { // Add a new node. - $node = $this->drupalCreateNode(array('type' => $nid_or_type)); + $extras['type'] = $nid_or_type; + $node = $this->drupalCreateNode($extras); $nid = $node->nid; // Save at least one revision to better simulate a real site. $this->drupalCreateNode(get_object_vars($node)); @@ -530,6 +540,7 @@ class FileFieldWidgetTestCase extends FileFieldTestCase { 'title' => $this->randomName(), ); $this->drupalPost('node/add/article', $edit, t('Save')); + $node = $this->drupalGetNodeByTitle($edit['title']); // Add a comment with a file. $text_file = $this->getTestFile('text'); @@ -559,6 +570,18 @@ class FileFieldWidgetTestCase extends FileFieldTestCase { $this->drupalLogout(); $this->drupalGet(file_create_url($comment_file->uri)); $this->assertResponse(403, t('Confirmed that access is denied for the file without the needed permission.')); + + // Unpublishes node. + $this->drupalLogin($this->admin_user); + $edit = array( + 'status' => FALSE, + ); + $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save')); + + // Ensures normal user can no longer download the file. + $this->drupalLogin($user); + $this->drupalGet(file_create_url($comment_file->uri)); + $this->assertResponse(403, t('Confirmed that access is denied for the file without the needed permission.')); } } @@ -1006,21 +1029,19 @@ class FileTokenReplaceTestCase extends FileFieldTestCase { // Load the node and the file. $node = node_load($nid, NULL, TRUE); - $file = (object) $node->{$field_name}[LANGUAGE_NONE][0]; - $file->description = 'File description.'; + $file = file_load($node->{$field_name}[LANGUAGE_NONE][0]['fid']); // Generate and test sanitized tokens. $tests = array(); $tests['[file:fid]'] = $file->fid; $tests['[file:name]'] = check_plain($file->filename); - $tests['[file:description]'] = filter_xss($file->description); - $tests['[file:path]'] = filter_xss($file->uri); - $tests['[file:mime]'] = filter_xss($file->filemime); + $tests['[file:path]'] = check_plain($file->uri); + $tests['[file:mime]'] = check_plain($file->filemime); $tests['[file:size]'] = format_size($file->filesize); - $tests['[file:url]'] = url(file_create_url($file->uri), $url_options); + $tests['[file:url]'] = check_plain(file_create_url($file->uri)); $tests['[file:timestamp]'] = format_date($file->timestamp, 'medium', '', NULL, $language->language); $tests['[file:timestamp:short]'] = format_date($file->timestamp, 'short', '', NULL, $language->language); - $tests['[file:owner]'] = $this->admin_user->name; + $tests['[file:owner]'] = check_plain(format_username($this->admin_user)); $tests['[file:owner:uid]'] = $file->uid; // Test to make sure that we generated something for each token. @@ -1033,7 +1054,6 @@ class FileTokenReplaceTestCase extends FileFieldTestCase { // Generate and test unsanitized tokens. $tests['[file:name]'] = $file->filename; - $tests['[file:description]'] = $file->description; $tests['[file:path]'] = $file->uri; $tests['[file:mime]'] = $file->filemime; $tests['[file:size]'] = format_size($file->filesize); @@ -1044,3 +1064,46 @@ class FileTokenReplaceTestCase extends FileFieldTestCase { } } } + +/** + * Test class to test file access on private nodes. + */ +class FilePrivateTestCase extends FileFieldTestCase { + public static function getInfo() { + return array( + 'name' => 'Private file test', + 'description' => 'Uploads a test to a private node and checks access.', + 'group' => 'File', + ); + } + + function setUp() { + parent::setUp('node_access_test'); + node_access_rebuild(); + variable_set('node_access_test_private', TRUE); + } + + /** + * Uploads a file to a private node, then tests that access is allowed and denied when appropriate. + */ + function testPrivateFile() { + // Use 'page' instead of 'article', so that the 'article' image field does + // not conflict with this test. If in the future the 'page' type gets its + // own default file or image field, this test can be made more robust by + // using a custom node type. + $type_name = 'page'; + $field_name = strtolower($this->randomName()); + $this->createFileField($field_name, $type_name, array('uri_scheme' => 'private')); + + $test_file = $this->getTestFile('text'); + $nid = $this->uploadNodeFile($test_file, $field_name, $type_name, TRUE, array('private' => TRUE)); + $node = node_load($nid, NULL, TRUE); + $node_file = (object) $node->{$field_name}[LANGUAGE_NONE][0]; + // Ensure the file can be downloaded. + $this->drupalGet(file_create_url($node_file->uri)); + $this->assertResponse(200, t('Confirmed that the generated URL is correct by downloading the shipped file.')); + $this->drupalLogOut(); + $this->drupalGet(file_create_url($node_file->uri)); + $this->assertNoResponse(200, t('Confirmed that access is denied for the file without the needed permission.')); + } +} diff --git a/modules/file/tests/file_module_test.info b/modules/file/tests/file_module_test.info index 80b5d649..a51ea690 100644 --- a/modules/file/tests/file_module_test.info +++ b/modules/file/tests/file_module_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/filter/filter.info b/modules/filter/filter.info index 049577c0..33fe235d 100644 --- a/modules/filter/filter.info +++ b/modules/filter/filter.info @@ -7,8 +7,8 @@ files[] = filter.test required = TRUE configure = admin/config/content/formats -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/filter/filter.test b/modules/filter/filter.test index a3d1bde4..67d08333 100644 --- a/modules/filter/filter.test +++ b/modules/filter/filter.test @@ -792,7 +792,7 @@ class FilterUnitTestCase extends DrupalUnitTestCase { */ function testLineBreakFilter() { // Setup dummy filter object. - $filter = new stdClass; + $filter = new stdClass(); $filter->callback = '_filter_autop'; // Since the line break filter naturally needs plenty of newlines in test @@ -1156,7 +1156,7 @@ class FilterUnitTestCase extends DrupalUnitTestCase { */ function testHtmlEscapeFilter() { // Setup dummy filter object. - $filter = new stdClass; + $filter = new stdClass(); $filter->callback = '_filter_html_escape'; $tests = array( @@ -1174,7 +1174,7 @@ class FilterUnitTestCase extends DrupalUnitTestCase { */ function testUrlFilter() { // Setup dummy filter object. - $filter = new stdClass; + $filter = new stdClass(); $filter->callback = '_filter_url'; $filter->settings = array( 'filter_url_length' => 496, @@ -1509,7 +1509,7 @@ www.example.com with a newline in comments --> */ function testUrlFilterContent() { // Setup dummy filter object. - $filter = new stdClass; + $filter = new stdClass(); $filter->settings = array( 'filter_url_length' => 496, ); diff --git a/modules/forum/forum.info b/modules/forum/forum.info index 00f5fce7..85e7daca 100644 --- a/modules/forum/forum.info +++ b/modules/forum/forum.info @@ -9,8 +9,8 @@ files[] = forum.test configure = admin/structure/forum stylesheets[all][] = forum.css -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/help/help.info b/modules/help/help.info index e944227e..b6db9d2e 100644 --- a/modules/help/help.info +++ b/modules/help/help.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x files[] = help.test -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/image/image.info b/modules/image/image.info index 401cd050..830c0a19 100644 --- a/modules/image/image.info +++ b/modules/image/image.info @@ -7,8 +7,8 @@ dependencies[] = file files[] = image.test configure = admin/config/media/image-styles -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/image/tests/image_module_test.info b/modules/image/tests/image_module_test.info index ffa11f00..7d851117 100644 --- a/modules/image/tests/image_module_test.info +++ b/modules/image/tests/image_module_test.info @@ -6,8 +6,8 @@ core = 7.x files[] = image_module_test.module hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/locale/locale-rtl.css b/modules/locale/locale-rtl.css new file mode 100644 index 00000000..aaf1988d --- /dev/null +++ b/modules/locale/locale-rtl.css @@ -0,0 +1,12 @@ + +#locale-translation-filter-form .form-item-language, +#locale-translation-filter-form .form-item-translation, +#locale-translation-filter-form .form-item-group { + float: right; + padding-left: .8em; + padding-right: 0; +} +#locale-translation-filter-form .form-actions { + float: right; + padding: 3ex 1em 0 0; +} diff --git a/modules/locale/locale.css b/modules/locale/locale.css index 1d875a2b..38112b50 100644 --- a/modules/locale/locale.css +++ b/modules/locale/locale.css @@ -21,14 +21,12 @@ width: 100%; } #locale-translation-filter-form .form-actions { - float: left; - padding: 3ex 0 0 1em; + float: left; /* LTR */ + padding: 3ex 0 0 1em; /* LTR */ } - .language-switcher-locale-session a.active { color: #0062A0; } - .language-switcher-locale-session a.session-active { color: #000000; } diff --git a/modules/locale/locale.info b/modules/locale/locale.info index 7489d334..6a62bb7f 100644 --- a/modules/locale/locale.info +++ b/modules/locale/locale.info @@ -6,8 +6,8 @@ core = 7.x files[] = locale.test configure = admin/config/regional/language -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/locale/locale.test b/modules/locale/locale.test index 42a6dbc4..3ae6d91a 100644 --- a/modules/locale/locale.test +++ b/modules/locale/locale.test @@ -2137,6 +2137,11 @@ class LocaleMultilingualFieldsFunctionalTest extends DrupalWebTestCase { ); $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type')); $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), t('Basic page content type has been updated.')); + + // Make node body translatable. + $field = field_info_field('body'); + $field['translatable'] = TRUE; + field_update_field($field); } /** diff --git a/modules/locale/tests/locale_test.info b/modules/locale/tests/locale_test.info index 41b5cb99..f966df08 100644 --- a/modules/locale/tests/locale_test.info +++ b/modules/locale/tests/locale_test.info @@ -5,8 +5,8 @@ package = Testing version = VERSION hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/menu/menu.info b/modules/menu/menu.info index 4ab447a3..88eab965 100644 --- a/modules/menu/menu.info +++ b/modules/menu/menu.info @@ -6,8 +6,8 @@ core = 7.x files[] = menu.test configure = admin/structure/menu -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/menu/menu.install b/modules/menu/menu.install index 717c5e71..13cb3cb5 100644 --- a/modules/menu/menu.install +++ b/modules/menu/menu.install @@ -108,6 +108,58 @@ function menu_update_7000() { } } +/** + * Rename "Primary Links" and "Secondary Links" to their Drupal 7 equivalents. + */ +function menu_update_7001() { + // Migrate D6 menu_primary_links_source to D7 menu_main_links_source (without + // renaming). + if (variable_get('menu_primary_links_source') !== NULL) { + variable_set('menu_main_links_source', variable_get('menu_primary_links_source')); + variable_del('menu_primary_links_source'); + } + + // Rename each menu, and any settings that refer to the old menu name. + $rename = array( + 'primary-links' => array('main-menu', 'Main menu'), + 'secondary-links' => array('secondary-menu', 'Secondary menu'), + ); + foreach ($rename as $from_menu => $to) { + list($to_menu, $to_title) = $to; + // Rename the menu, and links in the menu. + db_update('menu_custom') + ->fields(array('menu_name' => $to_menu, 'title' => $to_title)) + ->condition('menu_name', $from_menu) + ->execute(); + db_update('menu_links') + ->fields(array('menu_name' => $to_menu)) + ->condition('menu_name', $from_menu) + ->execute(); + + // Update any content type that used this menu as a default menu. + // Note: these variables may be unset/default, in which case we leave them + // alone. See menu_update_7000() + foreach (_update_7000_node_get_types() as $type => $type_object) { + $menu_options = variable_get('menu_options_' . $type); + if ($menu_options !== NULL) { + variable_set('menu_options_' . $type, str_replace($from_menu, $to_menu, $menu_options)); + if (variable_get('menu_parent_' . $type) == $from_menu . ':0') { + variable_set('menu_parent_' . $type, $to_menu . ':0'); + } + } + } + + // Update the "source for primary links" and "source for secondary links" to + // follow. + if (variable_get('menu_main_links_source') == $from_menu) { + variable_set('menu_main_links_source', $to_menu); + } + if (variable_get('menu_secondary_links_source') == $from_menu) { + variable_set('menu_secondary_links_source', $to_menu); + } + } +} + /** * @} End of "defgroup updates-7.x-extra" * The next series of updates should start at 8000. diff --git a/modules/node/node.api.php b/modules/node/node.api.php index 90ffd8b7..bc2eb65b 100644 --- a/modules/node/node.api.php +++ b/modules/node/node.api.php @@ -1022,7 +1022,7 @@ function hook_node_type_delete($info) { */ function hook_delete($node) { db_delete('mytable') - ->condition('nid', $nid->nid) + ->condition('nid', $node->nid) ->execute(); } diff --git a/modules/node/node.info b/modules/node/node.info index c33a80eb..bb9b933d 100644 --- a/modules/node/node.info +++ b/modules/node/node.info @@ -9,8 +9,8 @@ required = TRUE configure = admin/structure/types stylesheets[all][] = node.css -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/node/node.install b/modules/node/node.install index 852c1117..2498091f 100644 --- a/modules/node/node.install +++ b/modules/node/node.install @@ -476,7 +476,7 @@ function _update_7000_node_get_types() { $extra_types = array_diff($all_types, array_keys($node_types)); foreach ($extra_types as $type) { - $type_object = new stdClass; + $type_object = new stdClass(); $type_object->type = $type; // In Drupal 6, whether you have a body field or not is a flag in the node @@ -610,7 +610,6 @@ function node_update_7006(&$sandbox) { 'module' => 'text', 'cardinality' => 1, 'entity_types' => array('node'), - 'translatable' => TRUE, ); _update_7000_field_create_field($body_field); @@ -628,6 +627,8 @@ function node_update_7006(&$sandbox) { 'entity_type' => 'node', 'bundle' => $node_type->type, 'label' => $node_type->body_label, + 'description' => isset($node_type->description) ? $node_type->description : '', + 'required' => (isset($node_type->min_word_count) && $node_type->min_word_count > 0) ? 1 : 0, 'widget' => array( 'type' => 'text_textarea_with_summary', 'settings' => array( diff --git a/modules/node/node.module b/modules/node/node.module index 66e93c73..6c32a279 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -558,7 +558,6 @@ function node_add_body_field($type, $label = 'Body') { 'field_name' => 'body', 'type' => 'text_with_summary', 'entity_types' => array('node'), - 'translatable' => TRUE, ); $field = field_create_field($field); } @@ -1404,11 +1403,13 @@ function node_show($node, $message = FALSE) { drupal_set_title(t('Revision of %title from %date', array('%title' => $node->title, '%date' => format_date($node->revision_timestamp))), PASS_THROUGH); } + // For markup consistency with other pages, use node_view_multiple() rather than node_view(). + $nodes = node_view_multiple(array($node->nid => $node), 'full'); + // Update the history table, stating that this user viewed this node. node_tag_new($node); - // For markup consistency with other pages, use node_view_multiple() rather than node_view(). - return node_view_multiple(array($node->nid => $node), 'full'); + return $nodes; } /** @@ -2159,7 +2160,7 @@ function node_block_save($delta = '', $edit = array()) { } /** - * Find the most recent nodes that are available to the current user. + * Finds the most recently changed nodes that are available to the current user. * * @param $number * (optional) The maximum number of nodes to find. Defaults to 10. @@ -2415,7 +2416,10 @@ function node_block_list_alter(&$blocks) { } /** - * A generic function for generating RSS feeds from a set of nodes. + * Generates and prints an RSS feed. + * + * Generates an RSS feed from an array of node IDs, and prints it with an HTTP + * header, with Content Type set to RSS/XML. * * @param $nids * An array of node IDs (nid). Defaults to FALSE so empty feeds can be @@ -3337,6 +3341,9 @@ function node_access_acquire_grants($node, $delete = TRUE) { * node_access can use this function when doing mass updates due to widespread * permission changes. * + * Note: Don't call this function directly from a contributed module. Call + * node_access_acquire_grants() instead. + * * @param $node * The $node being written to. All that is necessary is that it contains a * nid. diff --git a/modules/node/tests/node_access_test.info b/modules/node/tests/node_access_test.info index f8775200..0c4815d3 100644 --- a/modules/node/tests/node_access_test.info +++ b/modules/node/tests/node_access_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/node/tests/node_access_test.install b/modules/node/tests/node_access_test.install index 3535ab19..1f33d51b 100644 --- a/modules/node/tests/node_access_test.install +++ b/modules/node/tests/node_access_test.install @@ -40,45 +40,3 @@ function node_access_test_schema() { return $schema; } -<?php - -/** - * @file - * Install, update and uninstall functions for the node_access_test module. - */ - -/** - * Implements hook_schema(). - */ -function node_access_test_schema() { - $schema['node_access_test'] = array( - 'description' => 'The base table for node_access_test.', - 'fields' => array( - 'nid' => array( - 'description' => 'The {node}.nid this record affects.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - 'private' => array( - 'description' => 'Boolean indicating whether the node is private (visible to administrator) or not (visible to non-administrators).', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - ), - 'indexes' => array( - 'nid' => array('nid'), - ), - 'primary key' => array('nid'), - 'foreign keys' => array( - 'versioned_node' => array( - 'table' => 'node', - 'columns' => array('nid' => 'nid'), - ), - ), - ); - - return $schema; -} \ No newline at end of file diff --git a/modules/node/tests/node_test.info b/modules/node/tests/node_test.info index 3ad84971..1499a40b 100644 --- a/modules/node/tests/node_test.info +++ b/modules/node/tests/node_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/node/tests/node_test_exception.info b/modules/node/tests/node_test_exception.info index b30b64b9..c49c0b95 100644 --- a/modules/node/tests/node_test_exception.info +++ b/modules/node/tests/node_test_exception.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/openid/openid.info b/modules/openid/openid.info index 8f7e176b..5f3f9152 100644 --- a/modules/openid/openid.info +++ b/modules/openid/openid.info @@ -5,8 +5,8 @@ package = Core core = 7.x files[] = openid.test -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/openid/tests/openid_test.info b/modules/openid/tests/openid_test.info index a40013ba..8652d3a0 100644 --- a/modules/openid/tests/openid_test.info +++ b/modules/openid/tests/openid_test.info @@ -6,8 +6,8 @@ core = 7.x dependencies[] = openid hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/overlay/overlay.info b/modules/overlay/overlay.info index 1688b0d4..85dbaccd 100644 --- a/modules/overlay/overlay.info +++ b/modules/overlay/overlay.info @@ -4,8 +4,8 @@ package = Core version = VERSION core = 7.x -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/path/path.info b/modules/path/path.info index ab494d3e..8fcdd55c 100644 --- a/modules/path/path.info +++ b/modules/path/path.info @@ -6,8 +6,8 @@ core = 7.x files[] = path.test configure = admin/config/search/path -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/path/path.test b/modules/path/path.test index 4112e5f6..f42ec81b 100644 --- a/modules/path/path.test +++ b/modules/path/path.test @@ -279,8 +279,9 @@ class PathLanguageTestCase extends DrupalWebTestCase { $this->drupalGet('node/' . $english_node->nid . '/translate'); $this->clickLink(t('add translation')); $edit = array(); + $langcode = LANGUAGE_NONE; $edit["title"] = $this->randomName(); - $edit["body[fr][0][value]"] = $this->randomName(); + $edit["body[$langcode][0][value]"] = $this->randomName(); $french_alias = $this->randomName(); $edit['path[alias]'] = $french_alias; $this->drupalPost(NULL, $edit, t('Save')); diff --git a/modules/php/php.info b/modules/php/php.info index 162c5fbe..95269827 100644 --- a/modules/php/php.info +++ b/modules/php/php.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x files[] = php.test -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/poll/poll.info b/modules/poll/poll.info index f53726e4..e5e3017c 100644 --- a/modules/poll/poll.info +++ b/modules/poll/poll.info @@ -6,8 +6,8 @@ core = 7.x files[] = poll.test stylesheets[all][] = poll.css -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/poll/poll.module b/modules/poll/poll.module index f45b8bda..86196957 100644 --- a/modules/poll/poll.module +++ b/modules/poll/poll.module @@ -485,6 +485,10 @@ function poll_load($nodes) { foreach ($nodes as $node) { $poll = db_query("SELECT runtime, active FROM {poll} WHERE nid = :nid", array(':nid' => $node->nid))->fetchObject(); + if (empty($poll)) { + $poll = new stdClass(); + } + // Load the appropriate choices into the $poll object. $poll->choice = db_select('poll_choice', 'c') ->addTag('translatable') diff --git a/modules/profile/profile.info b/modules/profile/profile.info index 59c28cb8..dc61b839 100644 --- a/modules/profile/profile.info +++ b/modules/profile/profile.info @@ -11,8 +11,8 @@ configure = admin/config/people/profile ; See user_system_info_alter(). hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/profile/profile.module b/modules/profile/profile.module index 2374fe8e..8cac6d79 100644 --- a/modules/profile/profile.module +++ b/modules/profile/profile.module @@ -544,6 +544,7 @@ function template_preprocess_profile_block(&$variables) { // Supply filtered version of $fields that have values. foreach ($variables['fields'] as $field) { if ($field->value) { + $variables['profile'][$field->name] = new stdClass(); $variables['profile'][$field->name]->title = check_plain($field->title); $variables['profile'][$field->name]->value = $field->value; $variables['profile'][$field->name]->type = $field->type; diff --git a/modules/rdf/rdf.info b/modules/rdf/rdf.info index 029ff2ce..416b3838 100644 --- a/modules/rdf/rdf.info +++ b/modules/rdf/rdf.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x files[] = rdf.test -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/rdf/tests/rdf_test.info b/modules/rdf/tests/rdf_test.info index a0ff30ba..00bd9256 100644 --- a/modules/rdf/tests/rdf_test.info +++ b/modules/rdf/tests/rdf_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/search/search.admin.inc b/modules/search/search.admin.inc index afa02def..d93c8528 100644 --- a/modules/search/search.admin.inc +++ b/modules/search/search.admin.inc @@ -143,7 +143,7 @@ function search_admin_settings($form) { */ function search_admin_settings_validate($form, &$form_state) { // Check whether we selected a valid default. - if ($form_state['clicked_button']['#value'] != t('Reset to defaults')) { + if ($form_state['triggering_element']['#value'] != t('Reset to defaults')) { $new_modules = array_filter($form_state['values']['search_active_modules']); $default = $form_state['values']['search_default_module']; if (!in_array($default, $new_modules, TRUE)) { @@ -164,7 +164,7 @@ function search_admin_settings_submit($form, &$form_state) { } $current_modules = variable_get('search_active_modules', array('node', 'user')); // Check whether we are resetting the values. - if ($form_state['clicked_button']['#value'] == t('Reset to defaults')) { + if ($form_state['triggering_element']['#value'] == t('Reset to defaults')) { $new_modules = array('node', 'user'); } else { diff --git a/modules/search/search.api.php b/modules/search/search.api.php index 557a56e5..8d6e2399 100644 --- a/modules/search/search.api.php +++ b/modules/search/search.api.php @@ -107,6 +107,10 @@ function hook_search_reset() { /** * Report the status of indexing. * + * The core search module only invokes this hook on active modules. + * Implementing modules do not need to check whether they are active when + * calculating their return values. + * * @return * An associative array with the key-value pairs: * - 'remaining': The number of items left to index. diff --git a/modules/search/search.info b/modules/search/search.info index b0032763..249b0bed 100644 --- a/modules/search/search.info +++ b/modules/search/search.info @@ -8,8 +8,8 @@ files[] = search.test configure = admin/config/search/settings stylesheets[all][] = search.css -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/search/tests/search_embedded_form.info b/modules/search/tests/search_embedded_form.info index de81aaec..d2f00ac6 100644 --- a/modules/search/tests/search_embedded_form.info +++ b/modules/search/tests/search_embedded_form.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/search/tests/search_embedded_form.module b/modules/search/tests/search_embedded_form.module index c0058f74..48457967 100644 --- a/modules/search/tests/search_embedded_form.module +++ b/modules/search/tests/search_embedded_form.module @@ -65,5 +65,6 @@ function search_embedded_form_form_submit($form, &$form_state) { * Adds the test form to search results. */ function search_embedded_form_preprocess_search_result(&$variables) { - $variables['snippet'] .= drupal_render(drupal_get_form('search_embedded_form_form')); + $form = drupal_get_form('search_embedded_form_form'); + $variables['snippet'] .= drupal_render($form); } diff --git a/modules/search/tests/search_extra_type.info b/modules/search/tests/search_extra_type.info index 32adacc9..06d86c5a 100644 --- a/modules/search/tests/search_extra_type.info +++ b/modules/search/tests/search_extra_type.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/shortcut/shortcut.info b/modules/shortcut/shortcut.info index 39728aa3..4eb2dbbd 100644 --- a/modules/shortcut/shortcut.info +++ b/modules/shortcut/shortcut.info @@ -6,8 +6,8 @@ core = 7.x files[] = shortcut.test configure = admin/config/user-interface/shortcut -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/shortcut/shortcut.install b/modules/shortcut/shortcut.install index 9dbab806..60ee6be8 100644 --- a/modules/shortcut/shortcut.install +++ b/modules/shortcut/shortcut.install @@ -25,6 +25,13 @@ function shortcut_install() { 'weight' => -19, ), ); + // If Drupal is being installed, rebuild the menu before saving the shortcut + // set, to make sure the links defined above can be correctly saved. (During + // installation, the menu might not have been built at all yet, or it might + // have been built but without the node module's links in it.) + if (drupal_installation_attempted()) { + menu_rebuild(); + } shortcut_set_save($shortcut_set); } diff --git a/modules/simpletest/simpletest.info b/modules/simpletest/simpletest.info index 42257dc3..b0273281 100644 --- a/modules/simpletest/simpletest.info +++ b/modules/simpletest/simpletest.info @@ -48,8 +48,8 @@ files[] = tests/upgrade/upgrade.taxonomy.test files[] = tests/upgrade/upgrade.upload.test files[] = tests/upgrade/upgrade.user.test -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/actions_loop_test.info b/modules/simpletest/tests/actions_loop_test.info index 701d0a20..14004058 100644 --- a/modules/simpletest/tests/actions_loop_test.info +++ b/modules/simpletest/tests/actions_loop_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/ajax_forms_test.info b/modules/simpletest/tests/ajax_forms_test.info index a2190461..5aecc800 100644 --- a/modules/simpletest/tests/ajax_forms_test.info +++ b/modules/simpletest/tests/ajax_forms_test.info @@ -5,8 +5,8 @@ package = Testing version = VERSION hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/ajax_test.info b/modules/simpletest/tests/ajax_test.info index 5cddb491..82d4fa82 100644 --- a/modules/simpletest/tests/ajax_test.info +++ b/modules/simpletest/tests/ajax_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/batch_test.info b/modules/simpletest/tests/batch_test.info index 602a4fd3..89e701c8 100644 --- a/modules/simpletest/tests/batch_test.info +++ b/modules/simpletest/tests/batch_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/common_test.info b/modules/simpletest/tests/common_test.info index 97ec552d..c11e1bab 100644 --- a/modules/simpletest/tests/common_test.info +++ b/modules/simpletest/tests/common_test.info @@ -7,8 +7,8 @@ stylesheets[all][] = common_test.css stylesheets[print][] = common_test.print.css hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/database_test.info b/modules/simpletest/tests/database_test.info index 7893409d..a6409a2c 100644 --- a/modules/simpletest/tests/database_test.info +++ b/modules/simpletest/tests/database_test.info @@ -5,8 +5,8 @@ package = Testing version = VERSION hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info b/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info index 52228081..44be97a8 100644 --- a/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info +++ b/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info b/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info index a170f8c7..255dc9ff 100644 --- a/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info +++ b/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/entity_cache_test.info b/modules/simpletest/tests/entity_cache_test.info index e977f7e6..f9b884e5 100644 --- a/modules/simpletest/tests/entity_cache_test.info +++ b/modules/simpletest/tests/entity_cache_test.info @@ -6,8 +6,8 @@ core = 7.x dependencies[] = entity_cache_test_dependency hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/entity_cache_test_dependency.info b/modules/simpletest/tests/entity_cache_test_dependency.info index 0dfe6eb3..ba4aa15f 100644 --- a/modules/simpletest/tests/entity_cache_test_dependency.info +++ b/modules/simpletest/tests/entity_cache_test_dependency.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/entity_crud_hook_test.info b/modules/simpletest/tests/entity_crud_hook_test.info index b4d8bedf..174cbf3e 100644 --- a/modules/simpletest/tests/entity_crud_hook_test.info +++ b/modules/simpletest/tests/entity_crud_hook_test.info @@ -5,8 +5,8 @@ package = Testing version = VERSION hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/entity_query.test b/modules/simpletest/tests/entity_query.test index d28d5a35..0fe8106e 100644 --- a/modules/simpletest/tests/entity_query.test +++ b/modules/simpletest/tests/entity_query.test @@ -1049,6 +1049,133 @@ class EntityFieldQueryTestCase extends DrupalWebTestCase { $this->assertTrue($pass, t("Can't query the universe.")); } + /** + * Tests field meta conditions. + */ + function testEntityFieldQueryMetaConditions() { + // Make a test field translatable. + $this->fields[0]['translatable'] = TRUE; + field_update_field($this->fields[0]); + field_test_entity_info_translatable('test_entity', TRUE); + drupal_static_reset('field_available_languages'); + + // Create more items with different languages. + $entity = new stdClass(); + $entity->ftid = 1; + $entity->ftvid = 1; + $entity->fttype = 'test_bundle'; + $j = 0; + + foreach (array(LANGUAGE_NONE, 'en') as $langcode) { + for ($i = 0; $i < 4; $i++) { + $entity->{$this->field_names[0]}[$langcode][$i]['value'] = $i + $j; + } + $j += 4; + } + + field_attach_update('test_entity', $entity); + + // Test delta field meta condition. + $query = new EntityFieldQuery(); + $query + ->entityCondition('entity_type', 'test_entity', '=') + ->fieldDeltaCondition($this->fields[0], 0, '>'); + $this->assertEntityFieldQuery($query, array( + array('test_entity', 1), + ), t('Test with a delta meta condition.')); + + // Test language field meta condition. + $query = new EntityFieldQuery(); + $query + ->entityCondition('entity_type', 'test_entity', '=') + ->fieldLanguageCondition($this->fields[0], LANGUAGE_NONE, '!='); + $this->assertEntityFieldQuery($query, array( + array('test_entity', 1), + ), t('Test with a language meta condition.')); + + // Test delta grouping. + $query = new EntityFieldQuery(); + $query + ->entityCondition('entity_type', 'test_entity', '=') + ->fieldCondition($this->fields[0], 'value', 0, '=', 'group') + ->fieldDeltaCondition($this->fields[0], 1, '<', 'group'); + $this->assertEntityFieldQuery($query, array( + array('test_entity', 1), + ), t('Test with a grouped delta meta condition.')); + + $query = new EntityFieldQuery(); + $query + ->entityCondition('entity_type', 'test_entity', '=') + ->fieldCondition($this->fields[0], 'value', 0, '=', 'group') + ->fieldDeltaCondition($this->fields[0], 1, '>=', 'group'); + $this->assertEntityFieldQuery($query, array(), t('Test with a grouped delta meta condition (empty result set).')); + + // Test language grouping. + $query = new EntityFieldQuery(); + $query + ->entityCondition('entity_type', 'test_entity', '=') + ->fieldCondition($this->fields[0], 'value', 0, '=', NULL, 'group') + ->fieldLanguageCondition($this->fields[0], 'en', '!=', NULL, 'group'); + $this->assertEntityFieldQuery($query, array( + array('test_entity', 1), + ), t('Test with a grouped language meta condition.')); + + $query = new EntityFieldQuery(); + $query + ->entityCondition('entity_type', 'test_entity', '=') + ->fieldCondition($this->fields[0], 'value', 0, '=', NULL, 'group') + ->fieldLanguageCondition($this->fields[0], LANGUAGE_NONE, '!=', NULL, 'group'); + $this->assertEntityFieldQuery($query, array(), t('Test with a grouped language meta condition (empty result set).')); + + // Test delta and language grouping. + $query = new EntityFieldQuery(); + $query + ->entityCondition('entity_type', 'test_entity', '=') + ->fieldCondition($this->fields[0], 'value', 0, '=', 'delta', 'language') + ->fieldDeltaCondition($this->fields[0], 1, '<', 'delta', 'language') + ->fieldLanguageCondition($this->fields[0], 'en', '!=', 'delta', 'language'); + $this->assertEntityFieldQuery($query, array( + array('test_entity', 1), + ), t('Test with a grouped delta + language meta condition.')); + + $query = new EntityFieldQuery(); + $query + ->entityCondition('entity_type', 'test_entity', '=') + ->fieldCondition($this->fields[0], 'value', 0, '=', 'delta', 'language') + ->fieldDeltaCondition($this->fields[0], 1, '>=', 'delta', 'language') + ->fieldLanguageCondition($this->fields[0], 'en', '!=', 'delta', 'language'); + $this->assertEntityFieldQuery($query, array(), t('Test with a grouped delta + language meta condition (empty result set, delta condition unsatisifed).')); + + $query = new EntityFieldQuery(); + $query + ->entityCondition('entity_type', 'test_entity', '=') + ->fieldCondition($this->fields[0], 'value', 0, '=', 'delta', 'language') + ->fieldDeltaCondition($this->fields[0], 1, '<', 'delta', 'language') + ->fieldLanguageCondition($this->fields[0], LANGUAGE_NONE, '!=', 'delta', 'language'); + $this->assertEntityFieldQuery($query, array(), t('Test with a grouped delta + language meta condition (empty result set, language condition unsatisifed).')); + + $query = new EntityFieldQuery(); + $query + ->entityCondition('entity_type', 'test_entity', '=') + ->fieldCondition($this->fields[0], 'value', 0, '=', 'delta', 'language') + ->fieldDeltaCondition($this->fields[0], 1, '>=', 'delta', 'language') + ->fieldLanguageCondition($this->fields[0], LANGUAGE_NONE, '!=', 'delta', 'language'); + $this->assertEntityFieldQuery($query, array(), t('Test with a grouped delta + language meta condition (empty result set, both conditions unsatisifed).')); + + // Test grouping with another field to ensure that grouping cache is reset + // properly. + $query = new EntityFieldQuery(); + $query + ->entityCondition('entity_type', 'test_entity_bundle', '=') + ->fieldCondition($this->fields[1], 'shape', 'circle', '=', 'delta', 'language') + ->fieldCondition($this->fields[1], 'color', 'blue', '=', 'delta', 'language') + ->fieldDeltaCondition($this->fields[1], 1, '=', 'delta', 'language') + ->fieldLanguageCondition($this->fields[1], LANGUAGE_NONE, '=', 'delta', 'language'); + $this->assertEntityFieldQuery($query, array( + array('test_entity_bundle', 5), + ), t('Test grouping cache.')); + } + /** * Tests the routing feature of EntityFieldQuery. */ diff --git a/modules/simpletest/tests/error_test.info b/modules/simpletest/tests/error_test.info index 9a0566d0..24796d83 100644 --- a/modules/simpletest/tests/error_test.info +++ b/modules/simpletest/tests/error_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/file.test b/modules/simpletest/tests/file.test index dc12b1b7..9dbe5464 100644 --- a/modules/simpletest/tests/file.test +++ b/modules/simpletest/tests/file.test @@ -196,10 +196,13 @@ class FileTestCase extends DrupalWebTestCase { * @return * File object. */ - function createFile($filepath = NULL, $contents = NULL, $scheme = 'public') { + function createFile($filepath = NULL, $contents = NULL, $scheme = NULL) { if (!isset($filepath)) { $filepath = $this->randomName(); } + if (!isset($scheme)) { + $scheme = file_default_scheme(); + } $filepath = $scheme . '://' . $filepath; if (!isset($contents)) { @@ -427,7 +430,7 @@ class FileValidatorTest extends DrupalWebTestCase { // Maximum size. if (image_get_toolkit()) { // Copy the image so that the original doesn't get resized. - copy(drupal_realpath('misc/druplicon.png'), 'temporary://druplicon.png'); + copy('misc/druplicon.png', 'temporary://druplicon.png'); $this->image->uri = 'temporary://druplicon.png'; $errors = file_validate_image_resolution($this->image, '10x5'); @@ -437,7 +440,7 @@ class FileValidatorTest extends DrupalWebTestCase { $this->assertTrue($info['width'] <= 10, t('Image scaled to correct width.'), 'File'); $this->assertTrue($info['height'] <= 5, t('Image scaled to correct height.'), 'File'); - drupal_unlink(drupal_realpath('temporary://druplicon.png')); + drupal_unlink('temporary://druplicon.png'); } else { // TODO: should check that the error is returned if no toolkit is available. @@ -531,17 +534,33 @@ class FileUnmanagedSaveDataTest extends FileTestCase { $filepath = file_unmanaged_save_data($contents); $this->assertTrue($filepath, t('Unnamed file saved correctly.')); $this->assertEqual(file_uri_scheme($filepath), file_default_scheme(), t("File was placed in Drupal's files directory.")); - $this->assertEqual($contents, file_get_contents(drupal_realpath($filepath)), t('Contents of the file are correct.')); + $this->assertEqual($contents, file_get_contents($filepath), t('Contents of the file are correct.')); // Provide a filename. $filepath = file_unmanaged_save_data($contents, 'public://asdf.txt', FILE_EXISTS_REPLACE); $this->assertTrue($filepath, t('Unnamed file saved correctly.')); $this->assertEqual('asdf.txt', basename($filepath), t('File was named correctly.')); - $this->assertEqual($contents, file_get_contents(drupal_realpath($filepath)), t('Contents of the file are correct.')); + $this->assertEqual($contents, file_get_contents($filepath), t('Contents of the file are correct.')); $this->assertFilePermissions($filepath, variable_get('file_chmod_file', 0664)); } } +/** + * Tests the file_unmanaged_save_data() function on remote filesystems. + */ +class RemoteFileUnmanagedSaveDataTest extends FileUnmanagedSaveDataTest { + public static function getInfo() { + $info = parent::getInfo(); + $info['group'] = 'File API (remote)'; + return $info; + } + + function setUp() { + parent::setUp('file_test'); + variable_set('file_default_scheme', 'dummy-remote'); + } +} + /** * Test the file_save_upload() function. */ @@ -862,6 +881,22 @@ class FileSaveUploadTest extends FileHookTestCase { } } +/** + * Test the file_save_upload() function on remote filesystems. + */ +class RemoteFileSaveUploadTest extends FileSaveUploadTest { + public static function getInfo() { + $info = parent::getInfo(); + $info['group'] = 'File API (remote)'; + return $info; + } + + function setUp() { + parent::setUp('file_test'); + variable_set('file_default_scheme', 'dummy-remote'); + } +} + /** * Directory related tests. */ @@ -879,7 +914,7 @@ class FileDirectoryTest extends FileTestCase { */ function testFileCheckDirectoryHandling() { // A directory to operate on. - $directory = file_stream_wrapper_get_instance_by_scheme(file_default_scheme())->getDirectoryPath() . '/' . $this->randomName() . '/' . $this->randomName(); + $directory = file_default_scheme() . '://' . $this->randomName() . '/' . $this->randomName(); $this->assertFalse(is_dir($directory), t('Directory does not exist prior to testing.')); // Non-existent directory. @@ -985,6 +1020,22 @@ class FileDirectoryTest extends FileTestCase { } } +/** + * Directory related tests. + */ +class RemoteFileDirectoryTest extends FileDirectoryTest { + public static function getInfo() { + $info = parent::getInfo(); + $info['group'] = 'File API (remote)'; + return $info; + } + + function setUp() { + parent::setUp('file_test'); + variable_set('file_default_scheme', 'dummy-remote'); + } +} + /** * Tests the file_scan_directory() function. */ @@ -1114,6 +1165,21 @@ class FileScanDirectoryTest extends FileTestCase { } } +/** + * Tests the file_scan_directory() function on remote filesystems. + */ +class RemoteFileScanDirectoryTest extends FileScanDirectoryTest { + public static function getInfo() { + $info = parent::getInfo(); + $info['group'] = 'File API (remote)'; + return $info; + } + + function setUp() { + parent::setUp('file_test'); + variable_set('file_default_scheme', 'dummy-remote'); + } +} /** * Deletion related tests. @@ -1160,6 +1226,21 @@ class FileUnmanagedDeleteTest extends FileTestCase { } } +/** + * Deletion related tests on remote filesystems. + */ +class RemoteFileUnmanagedDeleteTest extends FileUnmanagedDeleteTest { + public static function getInfo() { + $info = parent::getInfo(); + $info['group'] = 'File API (remote)'; + return $info; + } + + function setUp() { + parent::setUp('file_test'); + variable_set('file_default_scheme', 'dummy-remote'); + } +} /** * Deletion related tests. @@ -1237,6 +1318,21 @@ class FileUnmanagedDeleteRecursiveTest extends FileTestCase { } } +/** + * Deletion related tests on remote filesystems. + */ +class RemoteFileUnmanagedDeleteRecursiveTest extends FileUnmanagedDeleteRecursiveTest { + public static function getInfo() { + $info = parent::getInfo(); + $info['group'] = 'File API (remote)'; + return $info; + } + + function setUp() { + parent::setUp('file_test'); + variable_set('file_default_scheme', 'dummy-remote'); + } +} /** * Unmanaged move related tests. @@ -1310,6 +1406,21 @@ class FileUnmanagedMoveTest extends FileTestCase { } } +/** + * Unmanaged move related tests on remote filesystems. + */ +class RemoteFileUnmanagedMoveTest extends FileUnmanagedMoveTest { + public static function getInfo() { + $info = parent::getInfo(); + $info['group'] = 'File API (remote)'; + return $info; + } + + function setUp() { + parent::setUp('file_test'); + variable_set('file_default_scheme', 'dummy-remote'); + } +} /** * Unmanaged copy related tests. @@ -1399,6 +1510,22 @@ class FileUnmanagedCopyTest extends FileTestCase { } } +/** + * Unmanaged copy related tests on remote filesystems. + */ +class RemoteFileUnmanagedCopyTest extends FileUnmanagedCopyTest { + public static function getInfo() { + $info = parent::getInfo(); + $info['group'] = 'File API (remote)'; + return $info; + } + + function setUp() { + parent::setUp('file_test'); + variable_set('file_default_scheme', 'dummy-remote'); + } +} + /** * Deletion related tests. */ diff --git a/modules/simpletest/tests/file_test.info b/modules/simpletest/tests/file_test.info index d258299b..ee5e07d6 100644 --- a/modules/simpletest/tests/file_test.info +++ b/modules/simpletest/tests/file_test.info @@ -6,8 +6,8 @@ core = 7.x files[] = file_test.module hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/file_test.module b/modules/simpletest/tests/file_test.module index 2865a1fa..b3c43e07 100644 --- a/modules/simpletest/tests/file_test.module +++ b/modules/simpletest/tests/file_test.module @@ -37,6 +37,11 @@ function file_test_stream_wrappers() { 'class' => 'DrupalDummyStreamWrapper', 'description' => t('Dummy wrapper for simpletest.'), ), + 'dummy-remote' => array( + 'name' => t('Dummy files (remote)'), + 'class' => 'DrupalDummyRemoteStreamWrapper', + 'description' => t('Dummy wrapper for simpletest (remote).'), + ), ); } @@ -442,3 +447,15 @@ class DrupalDummyStreamWrapper extends DrupalLocalStreamWrapper { } } +/** + * Helper class for testing the stream wrapper registry. + * + * Dummy remote stream wrapper implementation (dummy-remote://). + * + * Basically just the public scheme but not returning a local file for realpath. + */ +class DrupalDummyRemoteStreamWrapper extends DrupalPublicStreamWrapper { + function realpath() { + return FALSE; + } +} diff --git a/modules/simpletest/tests/filter_test.info b/modules/simpletest/tests/filter_test.info index a77a6f50..825f82b8 100644 --- a/modules/simpletest/tests/filter_test.info +++ b/modules/simpletest/tests/filter_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/form_test.info b/modules/simpletest/tests/form_test.info index 29cb7fe8..d36a3ae9 100644 --- a/modules/simpletest/tests/form_test.info +++ b/modules/simpletest/tests/form_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/image_test.info b/modules/simpletest/tests/image_test.info index 7919f23c..a4b405d0 100644 --- a/modules/simpletest/tests/image_test.info +++ b/modules/simpletest/tests/image_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/mail.test b/modules/simpletest/tests/mail.test index 8a7b152d..a6c7b40e 100644 --- a/modules/simpletest/tests/mail.test +++ b/modules/simpletest/tests/mail.test @@ -1,6 +1,7 @@ <?php /** + * @file * Test the Drupal mailing system. */ class MailTestCase extends DrupalWebTestCase implements MailSystemInterface { @@ -63,3 +64,355 @@ class MailTestCase extends DrupalWebTestCase implements MailSystemInterface { } } +/** + * Unit tests for drupal_html_to_text(). + */ +class DrupalHtmlToTextTestCase extends DrupalWebTestCase { + public static function getInfo() { + return array( + 'name' => 'HTML to text conversion', + 'description' => 'Tests drupal_html_to_text().', + 'group' => 'Mail', + ); + } + + /** + * Converts a string to its PHP source equivalent for display in test messages. + * + * @param $text + * The text string to convert. + * + * @return + * An HTML representation of the text string that, when displayed in a + * browser, represents the PHP source code equivalent of $text. + */ + function stringToHtml($text) { + return '"' . + str_replace( + array("\n", ' '), + array('\n', ' '), + check_plain($text) + ) . '"'; + } + + /** + * Helper function for testing drupal_html_to_text(). + * + * @param $html + * The source HTML string to be converted. + * @param $text + * The expected result of converting $html to text. + * @param $message + * A text message to display in the assertion message. + * @param $allowed_tags + * (optional) An array of allowed tags, or NULL to default to the full + * set of tags supported by drupal_html_to_text(). + */ + function assertHtmlToText($html, $text, $message, $allowed_tags = NULL) { + preg_match_all('/<([a-z0-6]+)/', drupal_strtolower($html), $matches); + $tested_tags = implode(', ', array_unique($matches[1])); + $message .= ' (' . $tested_tags . ')'; + $result = drupal_html_to_text($html, $allowed_tags); + $pass = $this->assertEqual($result, $text, check_plain($message)); + $verbose = 'html = <pre>' . $this->stringToHtml($html) + . '</pre><br />' . 'result = <pre>' . $this->stringToHtml($result) + . '</pre><br />' . 'expected = <pre>' . $this->stringToHtml($text) + . '</pre>'; + $this->verbose($verbose); + if (!$pass) { + $this->pass("Previous test verbose info:<br />$verbose"); + } + } + + /** + * Test all supported tags of drupal_html_to_text(). + */ + function testTags() { + global $base_path, $base_url; + $tests = array( + // @todo Trailing linefeeds should be trimmed. + '<a href = "http://drupal.org">Drupal.org</a>' => "Drupal.org [1]\n\n[1] http://drupal.org\n", + // @todo Footer urls should be absolute. + "<a href = \"$base_path\">Homepage</a>" => "Homepage [1]\n\n[1] $base_url/\n", + '<address>Drupal</address>' => "Drupal\n", + // @todo The <address> tag is currently not supported. + '<address>Drupal</address><address>Drupal</address>' => "DrupalDrupal\n", + '<b>Drupal</b>' => "*Drupal*\n", + // @todo There should be a space between the '>' and the text. + '<blockquote>Drupal</blockquote>' => ">Drupal\n", + '<blockquote>Drupal</blockquote><blockquote>Drupal</blockquote>' => ">Drupal\n>Drupal\n", + '<br />Drupal<br />Drupal<br /><br />Drupal' => "Drupal\nDrupal\nDrupal\n", + '<br/>Drupal<br/>Drupal<br/><br/>Drupal' => "Drupal\nDrupal\nDrupal\n", + // @todo There should be two line breaks before the paragraph. + '<br/>Drupal<br/>Drupal<br/><br/>Drupal<p>Drupal</p>' => "Drupal\nDrupal\nDrupal\nDrupal\n\n", + '<div>Drupal</div>' => "Drupal\n", + // @todo The <div> tag is currently not supported. + '<div>Drupal</div><div>Drupal</div>' => "DrupalDrupal\n", + '<em>Drupal</em>' => "/Drupal/\n", + '<h1>Drupal</h1>' => "======== DRUPAL ==============================================================\n\n", + '<h1>Drupal</h1><p>Drupal</p>' => "======== DRUPAL ==============================================================\n\nDrupal\n\n", + '<h2>Drupal</h2>' => "-------- DRUPAL --------------------------------------------------------------\n\n", + '<h2>Drupal</h2><p>Drupal</p>' => "-------- DRUPAL --------------------------------------------------------------\n\nDrupal\n\n", + '<h3>Drupal</h3>' => ".... Drupal\n\n", + '<h3>Drupal</h3><p>Drupal</p>' => ".... Drupal\n\nDrupal\n\n", + '<h4>Drupal</h4>' => ".. Drupal\n\n", + '<h4>Drupal</h4><p>Drupal</p>' => ".. Drupal\n\nDrupal\n\n", + '<h5>Drupal</h5>' => "Drupal\n\n", + '<h5>Drupal</h5><p>Drupal</p>' => "Drupal\n\nDrupal\n\n", + '<h6>Drupal</h6>' => "Drupal\n\n", + '<h6>Drupal</h6><p>Drupal</p>' => "Drupal\n\nDrupal\n\n", + '<hr />Drupal<hr />' => "------------------------------------------------------------------------------\nDrupal\n------------------------------------------------------------------------------\n", + '<hr/>Drupal<hr/>' => "------------------------------------------------------------------------------\nDrupal\n------------------------------------------------------------------------------\n", + '<hr/>Drupal<hr/><p>Drupal</p>' => "------------------------------------------------------------------------------\nDrupal\n------------------------------------------------------------------------------\nDrupal\n\n", + '<i>Drupal</i>' => "/Drupal/\n", + '<p>Drupal</p>' => "Drupal\n\n", + '<p>Drupal</p><p>Drupal</p>' => "Drupal\n\nDrupal\n\n", + '<strong>Drupal</strong>' => "*Drupal*\n", + // @todo Tables are currently not supported. + '<table><tr><td>Drupal</td><td>Drupal</td></tr><tr><td>Drupal</td><td>Drupal</td></tr></table>' => "DrupalDrupalDrupalDrupal\n", + '<table><tr><td>Drupal</td></tr></table><p>Drupal</p>' => "Drupal\nDrupal\n\n", + // @todo The <u> tag is currently not supported. + '<u>Drupal</u>' => "Drupal\n", + '<ul><li>Drupal</li></ul>' => " * Drupal\n\n", + '<ul><li>Drupal <em>Drupal</em> Drupal</li></ul>' => " * Drupal /Drupal/ Drupal\n\n", + // @todo Lines containing nothing but spaces should be trimmed. + '<ul><li>Drupal</li><li><ol><li>Drupal</li><li>Drupal</li></ol></li></ul>' => " * Drupal\n * 1) Drupal\n 2) Drupal\n \n\n", + '<ul><li>Drupal</li><li><ol><li>Drupal</li></ol></li><li>Drupal</li></ul>' => " * Drupal\n * 1) Drupal\n \n * Drupal\n\n", + '<ul><li>Drupal</li><li>Drupal</li></ul>' => " * Drupal\n * Drupal\n\n", + '<ul><li>Drupal</li></ul><p>Drupal</p>' => " * Drupal\n\nDrupal\n\n", + '<ol><li>Drupal</li></ol>' => " 1) Drupal\n\n", + '<ol><li>Drupal</li><li><ul><li>Drupal</li><li>Drupal</li></ul></li></ol>' => " 1) Drupal\n 2) * Drupal\n * Drupal\n \n\n", + '<ol><li>Drupal</li><li>Drupal</li></ol>' => " 1) Drupal\n 2) Drupal\n\n", + '<ol>Drupal</ol>' => "Drupal\n\n", + '<ol><li>Drupal</li></ol><p>Drupal</p>' => " 1) Drupal\n\nDrupal\n\n", + '<dl><dt>Drupal</dt></dl>' => "Drupal\n\n", + '<dl><dt>Drupal</dt><dd>Drupal</dd></dl>' => "Drupal\n Drupal\n\n", + '<dl><dt>Drupal</dt><dd>Drupal</dd><dt>Drupal</dt><dd>Drupal</dd></dl>' => "Drupal\n Drupal\nDrupal\n Drupal\n\n", + '<dl><dt>Drupal</dt><dd>Drupal</dd></dl><p>Drupal</p>' => "Drupal\n Drupal\n\nDrupal\n\n", + '<dl><dt>Drupal<dd>Drupal</dl>' => "Drupal\n Drupal\n\n", + '<dl><dt>Drupal</dt></dl><p>Drupal</p>' => "Drupal\n\nDrupal\n\n", + // @todo Again, lines containing only spaces should be trimmed. + '<ul><li>Drupal</li><li><dl><dt>Drupal</dt><dd>Drupal</dd><dt>Drupal</dt><dd>Drupal</dd></dl></li><li>Drupal</li></ul>' => " * Drupal\n * Drupal\n Drupal\n Drupal\n Drupal\n \n * Drupal\n\n", + // Tests malformed HTML tags. + '<br>Drupal<br>Drupal' => "Drupal\nDrupal\n", + '<hr>Drupal<hr>Drupal' => "------------------------------------------------------------------------------\nDrupal\n------------------------------------------------------------------------------\nDrupal\n", + '<ol><li>Drupal<li>Drupal</ol>' => " 1) Drupal\n 2) Drupal\n\n", + '<ul><li>Drupal <em>Drupal</em> Drupal</ul></ul>' => " * Drupal /Drupal/ Drupal\n\n", + '<ul><li>Drupal<li>Drupal</ol>' => " * Drupal\n * Drupal\n\n", + '<ul><li>Drupal<li>Drupal</ul>' => " * Drupal\n * Drupal\n\n", + '<ul>Drupal</ul>' => "Drupal\n\n", + 'Drupal</ul></ol></dl><li>Drupal' => "Drupal\n * Drupal\n", + '<dl>Drupal</dl>' => "Drupal\n\n", + '<dl>Drupal</dl><p>Drupal</p>' => "Drupal\n\nDrupal\n\n", + '<dt>Drupal</dt>' => "Drupal\n", + // Tests some unsupported HTML tags. + '<html>Drupal</html>' => "Drupal\n", + // @todo Perhaps the contents of <script> tags should be dropped. + '<script type="text/javascript">Drupal</script>' => "Drupal\n", + ); + + foreach ($tests as $html => $text) { + $this->assertHtmlToText($html, $text, 'Supported tags'); + } + } + + /** + * Test $allowed_tags argument of drupal_html_to_text(). + */ + function testDrupalHtmlToTextArgs() { + // The second parameter of drupal_html_to_text() overrules the allowed tags. + $this->assertHtmlToText( + 'Drupal <b>Drupal</b> Drupal', + "Drupal *Drupal* Drupal\n", + 'Allowed <b> tag found', + array('b') + ); + $this->assertHtmlToText( + 'Drupal <h1>Drupal</h1> Drupal', + "Drupal Drupal Drupal\n", + 'Disallowed <h1> tag not found', + array('b') + ); + + $this->assertHtmlToText( + 'Drupal <p><em><b>Drupal</b></em><p> Drupal', + "Drupal Drupal Drupal\n", + 'Disallowed <p>, <em>, and <b> tags not found', + array('a', 'br', 'h1') + ); + + $this->assertHtmlToText( + '<html><body>Drupal</body></html>', + "Drupal\n", + 'Unsupported <html> and <body> tags not found', + array('html', 'body') + ); + } + + /** + * Test that whitespace is collapsed. + */ + function testDrupalHtmltoTextCollapsesWhitespace() { + $input = "<p>Drupal Drupal\n\nDrupal<pre>Drupal Drupal\n\nDrupal</pre>Drupal Drupal\n\nDrupal</p>"; + // @todo The whitespace should be collapsed. + $collapsed = "Drupal Drupal\n\nDrupalDrupal Drupal\n\nDrupalDrupal Drupal\n\nDrupal\n\n"; + $this->assertHtmlToText( + $input, + $collapsed, + 'Whitespace is collapsed', + array('p') + ); + } + + /** + * Test that text separated by block-level tags in HTML get separated by + * (at least) a newline in the plaintext version. + */ + function testDrupalHtmlToTextBlockTagToNewline() { + $input = '[text]' + . '<blockquote>[blockquote]</blockquote>' + . '<br />[br]' + . '<dl><dt>[dl-dt]</dt>' + . '<dt>[dt]</dt>' + . '<dd>[dd]</dd>' + . '<dd>[dd-dl]</dd></dl>' + . '<h1>[h1]</h1>' + . '<h2>[h2]</h2>' + . '<h3>[h3]</h3>' + . '<h4>[h4]</h4>' + . '<h5>[h5]</h5>' + . '<h6>[h6]</h6>' + . '<hr />[hr]' + . '<ol><li>[ol-li]</li>' + . '<li>[li]</li>' + . '<li>[li-ol]</li></ol>' + . '<p>[p]</p>' + . '<ul><li>[ul-li]</li>' + . '<li>[li-ul]</li></ul>' + . '[text]'; + $output = drupal_html_to_text($input); + $pass = $this->assertFalse( + preg_match('/\][^\n]*\[/s', $output), + 'Block-level HTML tags should force newlines' + ); + if (!$pass) { + $this->verbose($this->stringToHtml($output)); + } + $output_upper = drupal_strtoupper($output); + $upper_input = drupal_strtoupper($input); + $upper_output = drupal_html_to_text($upper_input); + $pass = $this->assertEqual( + $upper_output, + $output_upper, + 'Tag recognition should be case-insensitive' + ); + if (!$pass) { + $this->verbose( + $upper_output + . '<br />should be equal to <br />' + . $output_upper + ); + } + } + + /** + * Test that headers are properly separated from surrounding text. + */ + function testHeaderSeparation() { + $html = 'Drupal<h1>Drupal</h1>Drupal'; + // @todo There should be more space above the header than below it. + $text = "Drupal\n======== DRUPAL ==============================================================\n\nDrupal\n"; + $this->assertHtmlToText($html, $text, + 'Text before and after <h1> tag'); + $html = '<p>Drupal</p><h1>Drupal</h1>Drupal'; + // @todo There should be more space above the header than below it. + $text = "Drupal\n\n======== DRUPAL ==============================================================\n\nDrupal\n"; + $this->assertHtmlToText($html, $text, + 'Paragraph before and text after <h1> tag'); + $html = 'Drupal<h1>Drupal</h1><p>Drupal</p>'; + // @todo There should be more space above the header than below it. + $text = "Drupal\n======== DRUPAL ==============================================================\n\nDrupal\n\n"; + $this->assertHtmlToText($html, $text, + 'Text before and paragraph after <h1> tag'); + $html = '<p>Drupal</p><h1>Drupal</h1><p>Drupal</p>'; + $text = "Drupal\n\n======== DRUPAL ==============================================================\n\nDrupal\n\n"; + $this->assertHtmlToText($html, $text, + 'Paragraph before and after <h1> tag'); + } + + /** + * Test that footnote references are properly generated. + */ + function testFootnoteReferences() { + global $base_path, $base_url; + $source = '<a href="http://www.example.com/node/1">Host and path</a>' + . '<br /><a href="http://www.example.com">Host, no path</a>' + . '<br /><a href="' . $base_path . 'node/1">Path, no host</a>' + . '<br /><a href="node/1">Relative path</a>'; + // @todo Footnote urls should be absolute. + $tt = "Host and path [1]" + . "\nHost, no path [2]" + // @todo The following two references should be combined. + . "\nPath, no host [3]" + . "\nRelative path [4]" + . "\n" + . "\n[1] http://www.example.com/node/1" + . "\n[2] http://www.example.com" + // @todo The following two references should be combined. + . "\n[3] $base_url/node/1" + . "\n[4] node/1\n"; + $this->assertHtmlToText($source, $tt, 'Footnotes'); + } + + /** + * Test that combinations of paragraph breaks, line breaks, linefeeds, + * and spaces are properly handled. + */ + function testDrupalHtmlToTextParagraphs() { + $tests = array(); + $tests[] = array( + 'html' => "<p>line 1<br />\nline 2<br />line 3\n<br />line 4</p><p>paragraph</p>", + // @todo Trailing line breaks should be trimmed. + 'text' => "line 1\nline 2\nline 3\nline 4\n\nparagraph\n\n", + ); + $tests[] = array( + 'html' => "<p>line 1<br /> line 2</p> <p>line 4<br /> line 5</p> <p>0</p>", + // @todo Trailing line breaks should be trimmed. + 'text' => "line 1\nline 2\n\nline 4\nline 5\n\n0\n\n", + ); + foreach ($tests as $test) { + $this->assertHtmlToText($test['html'], $test['text'], 'Paragraph breaks'); + } + } + + /** + * Tests that drupal_html_to_text() wraps before 1000 characters. + * + * RFC 3676 says, "The Text/Plain media type is the lowest common + * denominator of Internet email, with lines of no more than 998 characters." + * + * RFC 2046 says, "SMTP [RFC-821] allows a maximum of 998 octets before the + * next CRLF sequence." + * + * RFC 821 says, "The maximum total length of a text line including the + * <CRLF> is 1000 characters." + */ + function testVeryLongLineWrap() { + $input = 'Drupal<br /><p>' . str_repeat('x', 2100) . '</><br />Drupal'; + $output = drupal_html_to_text($input); + // This awkward construct comes from includes/mail.inc lines 8-13. + $eol = variable_get('mail_line_endings', MAIL_LINE_ENDINGS); + // We must use strlen() rather than drupal_strlen() in order to count + // octets rather than characters. + $line_length_limit = 1000 - drupal_strlen($eol); + $maximum_line_length = 0; + foreach (explode($eol, $output) as $line) { + // We must use strlen() rather than drupal_strlen() in order to count + // octets rather than characters. + $maximum_line_length = max($maximum_line_length, strlen($line . $eol)); + } + $verbose = 'Maximum line length found was ' . $maximum_line_length . ' octets.'; + // @todo This should assert that $maximum_line_length <= 1000. + $this->pass($verbose); + } +} diff --git a/modules/simpletest/tests/menu.test b/modules/simpletest/tests/menu.test index 5642fcee..c0a79d4c 100644 --- a/modules/simpletest/tests/menu.test +++ b/modules/simpletest/tests/menu.test @@ -394,6 +394,14 @@ class MenuRouterTestCase extends DrupalWebTestCase { $this->assertEqual($link['plid'], $plid, t('%path plid @link_plid is equal to @plid.', array('%path' => $link['router_path'], '@link_plid' => $link['plid'], '@plid' => $plid))); } + /** + * Test menu_get_item() with empty ancestors. + */ + function testMenuGetItemNoAncestors() { + variable_set('menu_masks', array()); + $this->drupalGet(''); + } + /** * Test menu_set_item(). */ diff --git a/modules/simpletest/tests/menu_test.info b/modules/simpletest/tests/menu_test.info index 480b741a..87728df6 100644 --- a/modules/simpletest/tests/menu_test.info +++ b/modules/simpletest/tests/menu_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/module_test.info b/modules/simpletest/tests/module_test.info index 328307af..c7a7aaa3 100644 --- a/modules/simpletest/tests/module_test.info +++ b/modules/simpletest/tests/module_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/requirements1_test.info b/modules/simpletest/tests/requirements1_test.info index 5fb5dd04..f0de5df8 100644 --- a/modules/simpletest/tests/requirements1_test.info +++ b/modules/simpletest/tests/requirements1_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/requirements2_test.info b/modules/simpletest/tests/requirements2_test.info index 1952c423..4386779a 100644 --- a/modules/simpletest/tests/requirements2_test.info +++ b/modules/simpletest/tests/requirements2_test.info @@ -7,8 +7,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/session_test.info b/modules/simpletest/tests/session_test.info index 38e28a63..acdb06f5 100644 --- a/modules/simpletest/tests/session_test.info +++ b/modules/simpletest/tests/session_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/system_dependencies_test.info b/modules/simpletest/tests/system_dependencies_test.info index c6353303..df4cf74d 100644 --- a/modules/simpletest/tests/system_dependencies_test.info +++ b/modules/simpletest/tests/system_dependencies_test.info @@ -6,8 +6,8 @@ core = 7.x hidden = TRUE dependencies[] = _missing_dependency -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/system_test.info b/modules/simpletest/tests/system_test.info index 9e1bed97..a4d29cd1 100644 --- a/modules/simpletest/tests/system_test.info +++ b/modules/simpletest/tests/system_test.info @@ -6,8 +6,8 @@ core = 7.x files[] = system_test.module hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/taxonomy_test.info b/modules/simpletest/tests/taxonomy_test.info index 376a5bb3..e3e66e0f 100644 --- a/modules/simpletest/tests/taxonomy_test.info +++ b/modules/simpletest/tests/taxonomy_test.info @@ -6,8 +6,8 @@ core = 7.x hidden = TRUE dependencies[] = taxonomy -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/theme_test.info b/modules/simpletest/tests/theme_test.info index 721e469a..bd3a0bf8 100644 --- a/modules/simpletest/tests/theme_test.info +++ b/modules/simpletest/tests/theme_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/update_test_1.info b/modules/simpletest/tests/update_test_1.info index da04d6c1..808c126e 100644 --- a/modules/simpletest/tests/update_test_1.info +++ b/modules/simpletest/tests/update_test_1.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/update_test_2.info b/modules/simpletest/tests/update_test_2.info index da04d6c1..808c126e 100644 --- a/modules/simpletest/tests/update_test_2.info +++ b/modules/simpletest/tests/update_test_2.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/update_test_3.info b/modules/simpletest/tests/update_test_3.info index da04d6c1..808c126e 100644 --- a/modules/simpletest/tests/update_test_3.info +++ b/modules/simpletest/tests/update_test_3.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/upgrade/drupal-6.menu.database.php b/modules/simpletest/tests/upgrade/drupal-6.menu.database.php index d10c4eec..f5c588af 100644 --- a/modules/simpletest/tests/upgrade/drupal-6.menu.database.php +++ b/modules/simpletest/tests/upgrade/drupal-6.menu.database.php @@ -7,4 +7,123 @@ db_insert('variable')->fields(array( 'name' => 'menu_default_node_menu', 'value' => 's:15:"secondary-links";', )) +->values(array( + 'name' => 'menu_primary_links_source', + 'value' => 's:15:"secondary-links";', +)) +->values(array( + 'name' => 'menu_secondary_links_source', + 'value' => 's:13:"primary-links";', +)) +->execute(); + +// Add some links to the menus. +db_insert('menu_links')->fields(array( + 'menu_name', + 'mlid', + 'plid', + 'link_path', + 'router_path', + 'link_title', + 'options', + 'module', + 'hidden', + 'external', + 'has_children', + 'expanded', + 'weight', + 'depth', + 'customized', + 'p1', + 'p2', + 'p3', + 'p4', + 'p5', + 'p6', + 'p7', + 'p8', + 'p9', + 'updated', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '201', + 'plid' => '0', + 'link_path' => 'node/add', + 'router_path' => 'node/add', + 'link_title' => 'nodeadd-navigation', + 'options' => 'a:0:{}', + 'module' => 'menu', + 'hidden' => '0', + 'external' => '0', + 'has_children' => '1', + 'expanded' => '0', + 'weight' => '1', + 'depth' => '1', + 'customized' => '0', + 'p1' => '201', + 'p2' => '0', + 'p3' => '0', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'primary-links', + 'mlid' => '204', + 'plid' => '0', + 'link_path' => 'node/add', + 'router_path' => 'node/add', + 'link_title' => 'nodeadd-primary', + 'options' => 'a:0:{}', + 'module' => 'menu', + 'hidden' => '0', + 'external' => '0', + 'has_children' => '1', + 'expanded' => '0', + 'weight' => '1', + 'depth' => '1', + 'customized' => '0', + 'p1' => '204', + 'p2' => '0', + 'p3' => '0', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'secondary-links', + 'mlid' => '205', + 'plid' => '0', + 'link_path' => 'node/add', + 'router_path' => 'node/add', + 'link_title' => 'nodeadd-secondary', + 'options' => 'a:0:{}', + 'module' => 'menu', + 'hidden' => '0', + 'external' => '0', + 'has_children' => '1', + 'expanded' => '0', + 'weight' => '1', + 'depth' => '1', + 'customized' => '0', + 'p1' => '205', + 'p2' => '0', + 'p3' => '0', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) ->execute(); diff --git a/modules/simpletest/tests/upgrade/upgrade.menu.test b/modules/simpletest/tests/upgrade/upgrade.menu.test index beb20277..5a17a194 100644 --- a/modules/simpletest/tests/upgrade/upgrade.menu.test +++ b/modules/simpletest/tests/upgrade/upgrade.menu.test @@ -29,16 +29,50 @@ class MenuUpgradePathTestCase extends UpgradePathTestCase { public function testMenuUpgrade() { $this->assertTrue($this->performUpgrade(), t('The upgrade was completed successfully.')); - // Test the migration of "Default menu for content" setting to individual node types. - $this->drupalGet("admin/structure/types/manage/page/edit"); + // Test the migration of "Default menu for content" setting to individual + // node types. + $this->drupalGet('admin/structure/types/manage/page/edit'); $this->assertNoFieldChecked('edit-menu-options-management', 'Management menu is not selected as available menu'); $this->assertNoFieldChecked('edit-menu-options-navigation', 'Navigation menu is not selected as available menu'); - $this->assertNoFieldChecked('edit-menu-options-primary-links', 'Primary Links menu is not selected as available menu'); - $this->assertFieldChecked('edit-menu-options-secondary-links', 'Secondary Links menu is selected as available menu'); + $this->assertNoFieldChecked('edit-menu-options-main-menu', 'Main menu is not selected as available menu'); + $this->assertFieldChecked('edit-menu-options-secondary-menu', 'Secondary menu is selected as available menu'); $this->assertNoFieldChecked('edit-menu-options-user-menu', 'User menu is not selected as available menu'); - $this->assertOptionSelected('edit-menu-parent', 'secondary-links:0', 'Secondary links is selected as default parent item'); + $this->assertOptionSelected('edit-menu-parent', 'secondary-menu:0', 'Secondary menu is selected as default parent item'); $this->assertEqual(variable_get('menu_default_node_menu'), NULL, 'Redundant variable menu_default_node_menu has been removed'); + // Verify Primary/Secondary Links have been renamed. + $this->drupalGet('admin/structure/menu'); + $this->assertNoLinkByHref('admin/structure/menu/manage/primary-links'); + $this->assertLinkByHref('admin/structure/menu/manage/main-menu'); + $this->assertNoLinkByHref('admin/structure/menu/manage/secondary-links'); + $this->assertLinkByHref('admin/structure/menu/manage/secondary-menu'); + + // Verify the existence of all system-defined (default) menus. + foreach (menu_list_system_menus() as $menu_name => $title) { + $this->assertLinkByHref('admin/structure/menu/manage/' . $menu_name, 0, 'Found default menu: ' . $title); + } + + // Verify a few known links are still present, plus the ones created here. + $test_menus = array( + 'navigation' => array('Add content', 'nodeadd-navigation'), + 'management' => array('Administration', 'Account settings'), + 'user-menu' => array('My account', 'Log out'), + 'main-menu' => array('nodeadd-primary'), + 'secondary-menu' => array('nodeadd-secondary'), + ); + + foreach ($test_menus as $menu_name => $links) { + $this->drupalGet('admin/structure/menu/manage/' . $menu_name); + $this->assertResponse(200, 'Access menu management for ' . $menu_name); + foreach ($links as $link_text) { + $this->assertLink(t($link_text)); + } + } + + // Check the "source for primary/secondary links" setting. + $this->drupalGet('admin/structure/menu/settings'); + $this->assertOptionSelected('edit-menu-main-links-source', 'secondary-menu'); + $this->assertOptionSelected('edit-menu-secondary-links-source', 'main-menu'); } } diff --git a/modules/simpletest/tests/upgrade/upgrade.node.test b/modules/simpletest/tests/upgrade/upgrade.node.test index 163dbef5..cd44790c 100644 --- a/modules/simpletest/tests/upgrade/upgrade.node.test +++ b/modules/simpletest/tests/upgrade/upgrade.node.test @@ -27,6 +27,11 @@ class NodeBodyUpgradePathTestCase extends UpgradePathTestCase { */ public function testNodeBodyUpgrade() { $this->assertTrue($this->performUpgrade(), t('The upgrade was completed successfully.')); + + $instance = field_info_instance('node', 'body', 'story'); + $this->assertIdentical($instance['required'], 0, 'The required setting was preserved during the upgrade path.'); + $this->assertTrue($instance['description'], 'The description was preserved during the upgrade path'); + $this->drupalGet("content/1263769200"); $this->assertText('node body (broken) - 37'); diff --git a/modules/simpletest/tests/upgrade/upgrade.taxonomy.test b/modules/simpletest/tests/upgrade/upgrade.taxonomy.test index dadb98e5..37de0877 100644 --- a/modules/simpletest/tests/upgrade/upgrade.taxonomy.test +++ b/modules/simpletest/tests/upgrade/upgrade.taxonomy.test @@ -68,6 +68,12 @@ class UpgradePathTaxonomyTestCase extends UpgradePathTestCase { sort($inst_keys); $this->assertEqual($voc_keys, $inst_keys, t('Node type page has instances for every vocabulary.')); + // Ensure instance variables are getting through. + foreach ($instances as $instance) { + $this->assertTrue(isset($instance['required']), 'The required setting was preserved during the upgrade path.'); + $this->assertTrue($instance['description'], 'The description was preserved during the upgrade path'); + } + // Node type 'story' was not explicitly in $vocabulary->nodes but // each node of type 'story' was associated to one or more terms. // Check that the node type 'story' has been associated only to diff --git a/modules/simpletest/tests/url_alter_test.info b/modules/simpletest/tests/url_alter_test.info index ce07be55..2bcfc981 100644 --- a/modules/simpletest/tests/url_alter_test.info +++ b/modules/simpletest/tests/url_alter_test.info @@ -5,8 +5,8 @@ package = Testing version = VERSION hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/simpletest/tests/xmlrpc_test.info b/modules/simpletest/tests/xmlrpc_test.info index e30d855d..ac6df954 100644 --- a/modules/simpletest/tests/xmlrpc_test.info +++ b/modules/simpletest/tests/xmlrpc_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/statistics/statistics.info b/modules/statistics/statistics.info index 9746a792..02c27eae 100644 --- a/modules/statistics/statistics.info +++ b/modules/statistics/statistics.info @@ -6,8 +6,8 @@ core = 7.x files[] = statistics.test configure = admin/config/system/statistics -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/syslog/syslog.info b/modules/syslog/syslog.info index e8806a9e..9183fe4e 100644 --- a/modules/syslog/syslog.info +++ b/modules/syslog/syslog.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x files[] = syslog.test -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/system/image.gd.inc b/modules/system/image.gd.inc index a3f76d4a..39f86dc3 100644 --- a/modules/system/image.gd.inc +++ b/modules/system/image.gd.inc @@ -346,7 +346,7 @@ function image_gd_create_tmp(stdClass $image, $width, $height) { */ function image_gd_get_info(stdClass $image) { $details = FALSE; - $data = getimagesize(drupal_realpath($image->source)); + $data = getimagesize($image->source); if (isset($data) && is_array($data)) { $extensions = array('1' => 'gif', '2' => 'jpg', '3' => 'png'); diff --git a/modules/system/system.admin.inc b/modules/system/system.admin.inc index 9e7d69dd..0d3a8d7a 100644 --- a/modules/system/system.admin.inc +++ b/modules/system/system.admin.inc @@ -1757,7 +1757,7 @@ function system_file_system_settings() { '#title' => t('Private file system path'), '#default_value' => variable_get('file_private_path', ''), '#maxlength' => 255, - '#description' => t('A local file system path where private files will be stored. This directory must exist and be writable by Drupal. This directory should not be accessible over the web.'), + '#description' => t('An existing local file system path for storing private files. It should be writable by Drupal and not accessible over the web. See the online handbook for <a href="@handbook">more information about securing private files</a>.', array('@handbook' => 'http://drupal.org/handbook/modules/file')), '#after_build' => array('system_check_directory'), ); diff --git a/modules/system/system.api.php b/modules/system/system.api.php index 40053890..179f1231 100644 --- a/modules/system/system.api.php +++ b/modules/system/system.api.php @@ -1972,8 +1972,8 @@ function hook_permission() { * containing information about the hook. Each array may contain the * following elements: * - variables: (required if "render element" not present) An array of - * variables that this theme hook uses. This value allows the theme layer to - * properly utilize templates. Each array key represents the name of the + * variables that this theme hook uses. This value allows the theme layer + * to properly utilize templates. Each array key represents the name of the * variable and the value will be used as the default value if it is not * given when theme() is called. Template implementations receive these * arguments as variables in the template file. Function implementations @@ -1989,20 +1989,20 @@ function hook_permission() { * preprocess function (as needed) is actually loaded; this makes it * possible to split theme functions out into separate files quite easily. * - path: Override the path of the file to be used. Ordinarily the module or - * theme path will be used, but if the file will not be in the default path, - * include it here. This path should be relative to the Drupal root + * theme path will be used, but if the file will not be in the default + * path, include it here. This path should be relative to the Drupal root * directory. - * - template: If specified, this theme implementation is a template, and this - * is the template file without an extension. Do not put .tpl.php on this - * file; that extension will be added automatically by the default rendering - * engine (which is PHPTemplate). If 'path', above, is specified, the - * template should also be in this path. - * - function: If specified, this will be the function name to invoke for this - * implementation. If neither file nor function is specified, a default - * function name will be assumed. For example, if a module registers - * the 'node' theme hook, 'theme_node' will be assigned to its function. - * If the chameleon theme registers the node hook, it will be assigned - * 'chameleon_node' as its function. + * - template: If specified, this theme implementation is a template, and + * this is the template file without an extension. Do not put .tpl.php on + * this file; that extension will be added automatically by the default + * rendering engine (which is PHPTemplate). If 'path', above, is specified, + * the template should also be in this path. + * - function: If specified, this will be the function name to invoke for + * this implementation. If neither 'template' nor 'function' is specified, + * a default function name will be assumed. For example, if a module + * registers the 'node' theme hook, 'theme_node' will be assigned to its + * function. If the chameleon theme registers the node hook, it will be + * assigned 'chameleon_node' as its function. * - pattern: A regular expression pattern to be used to allow this theme * implementation to have a dynamic name. The convention is to use __ to * differentiate the dynamic portion of the theme. For example, to allow @@ -2017,11 +2017,11 @@ function hook_permission() { * a theme this will be filled in as phptemplate_preprocess and * phptemplate_preprocess_HOOK as well as themename_preprocess and * themename_preprocess_HOOK. - * - override preprocess functions: Set to TRUE when a theme does NOT want the - * standard preprocess functions to run. This can be used to give a theme - * FULL control over how variables are set. For example, if a theme wants - * total control over how certain variables in the page.tpl.php are set, - * this can be set to true. Please keep in mind that when this is used + * - override preprocess functions: Set to TRUE when a theme does NOT want + * the standard preprocess functions to run. This can be used to give a + * theme FULL control over how variables are set. For example, if a theme + * wants total control over how certain variables in the page.tpl.php are + * set, this can be set to true. Please keep in mind that when this is used * by a theme, that theme becomes responsible for making sure necessary * variables are set. * - type: (automatically derived) Where the theme hook is defined: @@ -2687,22 +2687,21 @@ function hook_file_delete($file) { * NULL. * * @see file_download() - * @see upload_file_download() */ function hook_file_download($uri) { // Check if the file is controlled by the current module. if (!file_prepare_directory($uri)) { $uri = FALSE; } - $result = db_query("SELECT f.* FROM {file_managed} f INNER JOIN {upload} u ON f.fid = u.fid WHERE uri = :uri", array('uri' => $uri)); - foreach ($result as $file) { - if (!user_access('view uploaded files')) { + if (strpos(file_uri_target($uri), variable_get('user_picture_path', 'pictures') . '/picture-') === 0) { + if (!user_access('access user profiles')) { + // Access to the file is denied. return -1; } - return array( - 'Content-Type' => $file->filemime, - 'Content-Length' => $file->filesize, - ); + else { + $info = image_get_info($uri); + return array('Content-Type' => $info['mime_type']); + } } } diff --git a/modules/system/system.info b/modules/system/system.info index fbb452fe..a3c517cb 100644 --- a/modules/system/system.info +++ b/modules/system/system.info @@ -12,8 +12,8 @@ files[] = system.test required = TRUE configure = admin/config/system -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/system/system.install b/modules/system/system.install index e0674446..e55c7cf3 100644 --- a/modules/system/system.install +++ b/modules/system/system.install @@ -2263,6 +2263,9 @@ function system_update_7042() { // provided any meaningful unique constraint ('pid' is a primary key). db_add_index('url_alias', 'source_language_pid', array('source', 'language', 'pid')); db_add_index('url_alias', 'alias_language_pid', array('alias', 'language', 'pid')); + + // Now that the URL aliases are correct, we can rebuild the whitelist. + drupal_path_alias_whitelist_rebuild(); } /** diff --git a/modules/system/system.module b/modules/system/system.module index c3b4a1e3..8fc0ffa4 100644 --- a/modules/system/system.module +++ b/modules/system/system.module @@ -3018,6 +3018,7 @@ function system_cron() { ->fields(array( 'expire' => 0, )) + ->condition('expire', 0, '<>') ->condition('expire', REQUEST_TIME, '<') ->execute(); } diff --git a/modules/system/system.test b/modules/system/system.test index 0fe0bc05..8a29ce53 100644 --- a/modules/system/system.test +++ b/modules/system/system.test @@ -1824,7 +1824,6 @@ class TokenReplaceTestCase extends DrupalWebTestCase { // Set a few site variables. variable_set('site_name', '<strong>Drupal<strong>'); variable_set('site_slogan', '<blink>Slogan</blink>'); - variable_set('site_mission', '<em>Mission</em>'); // Generate and test sanitized tokens. $tests = array(); diff --git a/modules/system/system.tokens.inc b/modules/system/system.tokens.inc index 27d7dfdb..56ddf298 100644 --- a/modules/system/system.tokens.inc +++ b/modules/system/system.tokens.inc @@ -88,10 +88,6 @@ function system_token_info() { 'name' => t("File name"), 'description' => t("The name of the file on disk."), ); - $file['description'] = array( - 'name' => t("Description"), - 'description' => t("An optional human-readable description of the file."), - ); $file['path'] = array( 'name' => t("Path"), 'description' => t("The location of the file relative to Drupal root."), @@ -228,10 +224,6 @@ function system_tokens($type, $tokens, array $data = array(), array $options = a $replacements[$original] = $sanitize ? check_plain($file->filename) : $file->filename; break; - case 'description': - $replacements[$original] = $sanitize ? check_plain($file->description) : $file->description; - break; - case 'path': $replacements[$original] = $sanitize ? check_plain($file->uri) : $file->uri; break; @@ -255,7 +247,8 @@ function system_tokens($type, $tokens, array $data = array(), array $options = a case 'owner': $account = user_load($file->uid); - $replacements[$original] = $sanitize ? check_plain($account->name) : $account->name; + $name = format_username($account); + $replacements[$original] = $sanitize ? check_plain($name) : $name; break; } } diff --git a/modules/taxonomy/taxonomy.admin.inc b/modules/taxonomy/taxonomy.admin.inc index d83f5d36..a236cfed 100644 --- a/modules/taxonomy/taxonomy.admin.inc +++ b/modules/taxonomy/taxonomy.admin.inc @@ -209,7 +209,7 @@ function taxonomy_form_vocabulary_validate($form, &$form_state) { * @see taxonomy_form_vocabulary_validate() */ function taxonomy_form_vocabulary_submit($form, &$form_state) { - if ($form_state['clicked_button']['#value'] == t('Delete')) { + if ($form_state['triggering_element']['#value'] == t('Delete')) { // Rebuild the form to confirm vocabulary deletion. $form_state['rebuild'] = TRUE; $form_state['confirm_delete'] = TRUE; @@ -434,7 +434,7 @@ function taxonomy_overview_terms($form, &$form_state, $vocabulary) { * @see taxonomy_overview_terms() */ function taxonomy_overview_terms_submit($form, &$form_state) { - if ($form_state['clicked_button']['#value'] == t('Reset to alphabetical')) { + if ($form_state['triggering_element']['#value'] == t('Reset to alphabetical')) { // Execute the reset action. if ($form_state['values']['reset_alphabetical'] === TRUE) { return taxonomy_vocabulary_confirm_reset_alphabetical_submit($form, $form_state); @@ -674,9 +674,6 @@ function taxonomy_form_term($form, &$form_state, $edit = array(), $vocabulary = if (isset($form_state['confirm_delete'])) { return array_merge($form, taxonomy_term_confirm_delete($form, $form_state, $term->tid)); } - elseif (isset($form_state['confirm_parents'])) { - return array_merge($form, taxonomy_term_confirm_parents($form, $form_state, $vocabulary)); - } $form['name'] = array( '#type' => 'textfield', @@ -801,7 +798,7 @@ function taxonomy_form_term_validate($form, &$form_state) { * @see taxonomy_form_term() */ function taxonomy_form_term_submit($form, &$form_state) { - if ($form_state['clicked_button']['#value'] == t('Delete')) { + if ($form_state['triggering_element']['#value'] == t('Delete')) { // Execute the term deletion. if ($form_state['values']['delete'] === TRUE) { return taxonomy_term_confirm_delete_submit($form, $form_state); @@ -811,12 +808,6 @@ function taxonomy_form_term_submit($form, &$form_state) { $form_state['confirm_delete'] = TRUE; return; } - // Rebuild the form to confirm enabling multiple parents. - elseif ($form_state['clicked_button']['#value'] == t('Save') && count($form_state['values']['parent']) > 1 && $form['#vocabulary']->hierarchy < 2) { - $form_state['rebuild'] = TRUE; - $form_state['confirm_parents'] = TRUE; - return; - } $term = taxonomy_form_term_submit_build_taxonomy_term($form, $form_state); @@ -872,25 +863,6 @@ function taxonomy_form_term_submit_build_taxonomy_term($form, &$form_state) { return $term; } -/** - * Form builder for the confirmation of multiple term parents. - * - * @ingroup forms - * @see taxonomy_form_term() - */ -function taxonomy_term_confirm_parents($form, &$form_state, $vocabulary) { - foreach (element_children($form_state['values']) as $key) { - $form[$key] = array( - '#type' => 'value', - '#value' => $form_state['values'][$key], - ); - } - $question = t('Set multiple term parents?'); - $description = '<p>' . t("Adding multiple parents to a term will cause the %vocabulary vocabulary to look for multiple parents on every term. Because multiple parents are not supported when using the drag and drop outline interface, drag and drop will be disabled if you enable this option. If you choose to have multiple parents, you will only be able to set parents by using the term edit form.", array('%vocabulary' => $vocabulary->name)) . '</p>'; - $description .= '<p>' . t("You may re-enable the drag and drop interface at any time by reducing multiple parents to a single parent for the terms in this vocabulary.") . '</p>'; - return confirm_form($form, $question, drupal_get_destination(), $description, t('Set multiple parents')); -} - /** * Form builder for the term delete form. * diff --git a/modules/taxonomy/taxonomy.info b/modules/taxonomy/taxonomy.info index 2dea1189..231550d2 100644 --- a/modules/taxonomy/taxonomy.info +++ b/modules/taxonomy/taxonomy.info @@ -8,8 +8,8 @@ files[] = taxonomy.module files[] = taxonomy.test configure = admin/structure/taxonomy -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/taxonomy/taxonomy.install b/modules/taxonomy/taxonomy.install index 56b7e01c..68fbc780 100644 --- a/modules/taxonomy/taxonomy.install +++ b/modules/taxonomy/taxonomy.install @@ -438,6 +438,7 @@ function taxonomy_update_7004() { 'entity_type' => 'node', 'settings' => array(), 'description' => $vocabulary->help, + 'required' => $vocabulary->required, 'widget' => array(), 'display' => array( 'default' => array( diff --git a/modules/taxonomy/taxonomy.pages.inc b/modules/taxonomy/taxonomy.pages.inc index 3aed2901..0cca252d 100644 --- a/modules/taxonomy/taxonomy.pages.inc +++ b/modules/taxonomy/taxonomy.pages.inc @@ -110,7 +110,7 @@ function taxonomy_autocomplete($field_name, $tags_typed = '') { ->execute() ->fetchAllKeyed(); - $prefix = count($tags_typed) ? implode(', ', $tags_typed) . ', ' : ''; + $prefix = count($tags_typed) ? drupal_implode_tags($tags_typed) . ', ' : ''; $term_matches = array(); foreach ($tags_return as $tid => $name) { @@ -119,9 +119,7 @@ function taxonomy_autocomplete($field_name, $tags_typed = '') { if (strpos($name, ',') !== FALSE || strpos($name, '"') !== FALSE) { $n = '"' . str_replace('"', '""', $name) . '"'; } - else { - $term_matches[$prefix . $n] = check_plain($name); - } + $term_matches[$prefix . $n] = check_plain($name); } } diff --git a/modules/taxonomy/taxonomy.test b/modules/taxonomy/taxonomy.test index 97cfe448..aa7cc2e4 100644 --- a/modules/taxonomy/taxonomy.test +++ b/modules/taxonomy/taxonomy.test @@ -580,7 +580,7 @@ class TaxonomyTermTestCase extends TaxonomyWebTestCase { field_create_instance($instance); $terms = array( $this->randomName(), - $this->randomName(), + $this->randomName() . ', ' . $this->randomName(), $this->randomName(), ); @@ -590,7 +590,7 @@ class TaxonomyTermTestCase extends TaxonomyWebTestCase { $edit["body[$langcode][0][value]"] = $this->randomName(); // Insert the terms in a comma separated list. Vocabulary 1 is a // free-tagging field created by the default profile. - $edit[$instance['field_name'] . "[$langcode]"] = implode(', ', $terms); + $edit[$instance['field_name'] . "[$langcode]"] = drupal_implode_tags($terms); // Preview and verify the terms appear but are not created. $this->drupalPost('node/add/page', $edit, t('Preview')); @@ -611,9 +611,9 @@ class TaxonomyTermTestCase extends TaxonomyWebTestCase { } // Get the created terms. - list($term1, $term2, $term3) = taxonomy_get_tree($this->vocabulary->vid); + list($term1, $term2, $term3) = array_values(taxonomy_term_load_multiple(FALSE)); - // Delete one term. + // Delete term 1. $this->drupalPost('taxonomy/term/' . $term1->tid . '/edit', array(), t('Delete')); $this->drupalPost(NULL, NULL, t('Delete')); $term_names = array($term2->name, $term3->name); @@ -627,10 +627,17 @@ class TaxonomyTermTestCase extends TaxonomyWebTestCase { } $this->assertNoText($term1->name, t('The deleted term %name does not appear on the node page.', array('%name' => $term1->name))); - // Test autocomplete on term 2. + // Test autocomplete on term 2 - it contains a comma, so expect the key to + // be quoted. $input = substr($term2->name, 0, 3); $this->drupalGet('taxonomy/autocomplete/taxonomy_' . $this->vocabulary->machine_name . '/' . $input); - $this->assertRaw('{"' . $term2->name . '":"' . $term2->name . '"}', t('Autocomplete returns term %term_name after typing the first 3 letters.', array('%term_name' => $term2->name))); + $this->assertRaw('{"\"' . $term2->name . '\"":"' . $term2->name . '"}', t('Autocomplete returns term %term_name after typing the first 3 letters.', array('%term_name' => $term2->name))); + + // Test autocomplete on term 3 - it is alphanumeric only, so no extra + // quoting. + $input = substr($term3->name, 0, 3); + $this->drupalGet('taxonomy/autocomplete/taxonomy_' . $this->vocabulary->machine_name . '/' . $input); + $this->assertRaw('{"' . $term3->name . '":"' . $term3->name . '"}', t('Autocomplete returns term %term_name after typing the first 3 letters.', array('%term_name' => $term3->name))); } /** @@ -760,6 +767,35 @@ class TaxonomyTermTestCase extends TaxonomyWebTestCase { $this->assertEqual($terms[2]->parents, array($term2->tid), t('Term 3 is still a child of term 2.').var_export($terms[1]->tid,1)); } + /** + * Test saving a term with multiple parents through the UI. + */ + function testTermMultipleParentsInterface() { + // Add a new term to the vocabulary so that we can have multiple parents. + $parent = $this->createTerm($this->vocabulary); + + // Add a new term with multiple parents. + $edit = array( + 'name' => $this->randomName(12), + 'description[value]' => $this->randomName(100), + 'parent[]' => array(0, $parent->tid), + ); + // Save the new term. + $this->drupalPost('admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/add', $edit, t('Save')); + + // Check that the term was successfully created. + $terms = taxonomy_get_term_by_name($edit['name']); + $term = reset($terms); + $this->assertNotNull($term, t('Term found in database')); + $this->assertEqual($edit['name'], $term->name, t('Term name was successfully saved.')); + $this->assertEqual($edit['description[value]'], $term->description, t('Term description was successfully saved.')); + // Check that the parent tid is still there. The other parent (<root>) is + // not added by taxonomy_get_parents(). + $parents = taxonomy_get_parents($term->tid); + $parent = reset($parents); + $this->assertEqual($edit['parent[]'][1], $parent->tid, t('Term parents were successfully saved.')); + } + /** * Test taxonomy_get_term_by_name(). */ diff --git a/modules/toolbar/toolbar.info b/modules/toolbar/toolbar.info index 798d24a7..381d4dd4 100644 --- a/modules/toolbar/toolbar.info +++ b/modules/toolbar/toolbar.info @@ -4,8 +4,8 @@ core = 7.x package = Core version = VERSION -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/tracker/tracker.info b/modules/tracker/tracker.info index db7549bb..f9326483 100644 --- a/modules/tracker/tracker.info +++ b/modules/tracker/tracker.info @@ -6,8 +6,8 @@ version = VERSION core = 7.x files[] = tracker.test -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/translation/tests/translation_test.info b/modules/translation/tests/translation_test.info index 467f4935..39bda0d0 100644 --- a/modules/translation/tests/translation_test.info +++ b/modules/translation/tests/translation_test.info @@ -5,8 +5,8 @@ package = Testing version = VERSION hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/translation/translation.info b/modules/translation/translation.info index d7cd35fd..5ce3c142 100644 --- a/modules/translation/translation.info +++ b/modules/translation/translation.info @@ -6,8 +6,8 @@ version = VERSION core = 7.x files[] = translation.test -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/translation/translation.test b/modules/translation/translation.test index 54b53d9f..fe320a93 100644 --- a/modules/translation/translation.test +++ b/modules/translation/translation.test @@ -108,9 +108,9 @@ class TranslationTestCase extends DrupalWebTestCase { // Update original and mark translation as outdated. $node_body = $this->randomName(); - $node->body[$node->language][0]['value'] = $node_body; + $node->body[LANGUAGE_NONE][0]['value'] = $node_body; $edit = array(); - $edit["body[$node->language][0][value]"] = $node_body; + $edit["body[$langcode][0][value]"] = $node_body; $edit['translation[retranslate]'] = TRUE; $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save')); $this->assertRaw(t('Basic page %title has been updated.', array('%title' => $node_title)), t('Original node updated.')); @@ -121,7 +121,7 @@ class TranslationTestCase extends DrupalWebTestCase { // Update translation and mark as updated. $edit = array(); - $edit["body[$node_translation->language][0][value]"] = $this->randomName(); + $edit["body[$langcode][0][value]"] = $this->randomName(); $edit['translation[status]'] = FALSE; $this->drupalPost('node/' . $node_translation->nid . '/edit', $edit, t('Save')); $this->assertRaw(t('Basic page %title has been updated.', array('%title' => $node_translation_title)), t('Translated node updated.')); @@ -131,7 +131,7 @@ class TranslationTestCase extends DrupalWebTestCase { $this->drupalGet('node/add/page'); $this->assertFieldByXPath('//select[@name="language"]//option', 'it', t('Italian (disabled) is available in language selection.')); $translation_it = $this->createTranslation($node, $this->randomName(), $this->randomName(), 'it'); - $this->assertRaw($translation_it->body['it'][0]['value'], t('Content created in Italian (disabled).')); + $this->assertRaw($translation_it->body[LANGUAGE_NONE][0]['value'], t('Content created in Italian (disabled).')); // Confirm that language neutral is an option for translators when there are // disabled languages. @@ -349,9 +349,10 @@ class TranslationTestCase extends DrupalWebTestCase { function createTranslation($node, $title, $body, $language) { $this->drupalGet('node/add/page', array('query' => array('translation' => $node->nid, 'target' => $language))); - $body_key = "body[$language][0][value]"; + $langcode = LANGUAGE_NONE; + $body_key = "body[$langcode][0][value]"; $this->assertFieldByXPath('//input[@id="edit-title"]', $node->title, "Original title value correctly populated."); - $this->assertFieldByXPath("//textarea[@name='$body_key']", $node->body[$node->language][0]['value'], "Original body value correctly populated."); + $this->assertFieldByXPath("//textarea[@name='$body_key']", $node->body[LANGUAGE_NONE][0]['value'], "Original body value correctly populated."); $edit = array(); $edit["title"] = $title; diff --git a/modules/trigger/tests/trigger_test.info b/modules/trigger/tests/trigger_test.info index 406a1af1..67fe0749 100644 --- a/modules/trigger/tests/trigger_test.info +++ b/modules/trigger/tests/trigger_test.info @@ -4,8 +4,8 @@ package = Testing core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/trigger/trigger.info b/modules/trigger/trigger.info index 8c460549..88e1afc1 100644 --- a/modules/trigger/trigger.info +++ b/modules/trigger/trigger.info @@ -6,8 +6,8 @@ core = 7.x files[] = trigger.test configure = admin/structure/trigger -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/update/tests/aaa_update_test.info b/modules/update/tests/aaa_update_test.info index dd1becd4..d39efaf3 100644 --- a/modules/update/tests/aaa_update_test.info +++ b/modules/update/tests/aaa_update_test.info @@ -4,8 +4,8 @@ package = Testing core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/update/tests/bbb_update_test.info b/modules/update/tests/bbb_update_test.info index f6ed550d..2bd0175a 100644 --- a/modules/update/tests/bbb_update_test.info +++ b/modules/update/tests/bbb_update_test.info @@ -4,8 +4,8 @@ package = Testing core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/update/tests/ccc_update_test.info b/modules/update/tests/ccc_update_test.info index a5190eff..f715441e 100644 --- a/modules/update/tests/ccc_update_test.info +++ b/modules/update/tests/ccc_update_test.info @@ -4,8 +4,8 @@ package = Testing core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/update/tests/update_test.info b/modules/update/tests/update_test.info index 0f0d649e..effe5538 100644 --- a/modules/update/tests/update_test.info +++ b/modules/update/tests/update_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/update/update.info b/modules/update/update.info index 2b53994b..51aacf44 100644 --- a/modules/update/update.info +++ b/modules/update/update.info @@ -6,8 +6,8 @@ core = 7.x files[] = update.test configure = admin/reports/updates/settings -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/user/tests/user_form_test.info b/modules/user/tests/user_form_test.info index 8e9af847..a38e3b88 100644 --- a/modules/user/tests/user_form_test.info +++ b/modules/user/tests/user_form_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/user/user-rtl.css b/modules/user/user-rtl.css index 5a1442c1..642c9434 100644 --- a/modules/user/user-rtl.css +++ b/modules/user/user-rtl.css @@ -4,6 +4,12 @@ padding-right: 1.5em; } +#user-admin-roles .form-item-name { + float: right; + margin-left: 1em; + margin-right: 0; +} + /** * Password strength indicator. */ diff --git a/modules/user/user.admin.inc b/modules/user/user.admin.inc index 0596bde4..0044b18a 100644 --- a/modules/user/user.admin.inc +++ b/modules/user/user.admin.inc @@ -712,7 +712,12 @@ function user_admin_permissions($form, $form_state, $rid = NULL) { // Have to build checkboxes here after checkbox arrays are built foreach ($role_names as $rid => $name) { - $form['checkboxes'][$rid] = array('#type' => 'checkboxes', '#options' => $options, '#default_value' => isset($status[$rid]) ? $status[$rid] : array()); + $form['checkboxes'][$rid] = array( + '#type' => 'checkboxes', + '#options' => $options, + '#default_value' => isset($status[$rid]) ? $status[$rid] : array(), + '#attributes' => array('class' => array('rid-' . $rid)), + ); $form['role_names'][$rid] = array('#markup' => check_plain($name), '#tree' => TRUE); } diff --git a/modules/user/user.css b/modules/user/user.css index d6ed7c36..079ec38a 100644 --- a/modules/user/user.css +++ b/modules/user/user.css @@ -22,8 +22,8 @@ clear: both; } #user-admin-roles .form-item-name { - float: left; - margin-right: 1em; + float: left; /* LTR */ + margin-right: 1em; /* LTR */ } /** diff --git a/modules/user/user.info b/modules/user/user.info index 27f47350..04f0f7b7 100644 --- a/modules/user/user.info +++ b/modules/user/user.info @@ -9,8 +9,8 @@ required = TRUE configure = admin/config/people stylesheets[all][] = user.css -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/modules/user/user.module b/modules/user/user.module index 84430b2f..044ad469 100644 --- a/modules/user/user.module +++ b/modules/user/user.module @@ -74,10 +74,26 @@ function user_help($path, $arg) { } /** - * Invokes hook_user() in every module. + * Invokes a user hook in every module. * * We cannot use module_invoke() for this, because the arguments need to * be passed by reference. + * + * @param $type + * A text string that controls which user hook to invoke. Valid choices are: + * - cancel: Invokes hook_user_cancel(). + * - insert: Invokes hook_user_insert(). + * - login: Invokes hook_user_login(). + * - presave: Invokes hook_user_presave(). + * - update: Invokes hook_user_update(). + * @param $edit + * An associative array variable containing form values to be passed + * as the first parameter of the hook function. + * @param $account + * The user account object to be passed as the second parameter of the hook + * function. + * @param $category + * The category of user information being acted upon. */ function user_module_invoke($type, &$edit, $account, $category = NULL) { foreach (module_implements('user_' . $type) as $module) { @@ -2287,6 +2303,27 @@ function user_cancel_url($account) { return url("user/$account->uid/cancel/confirm/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login), array('absolute' => TRUE)); } +/** + * Creates a unique hash value for use in time-dependent per-user URLs. + * + * This hash is normally used to build a unique and secure URL that is sent to + * the user by email for purposes such as resetting the user's password. In + * order to validate the URL, the same hash can be generated again, from the + * same information, and compared to the hash value from the URL. The URL + * normally contains both the time stamp and the numeric user ID. The login + * name and hashed password are retrieved from the database as necessary. For a + * usage example, see user_cancel_url() and user_cancel_confirm(). + * + * @param $password + * The hashed user account password value. + * @param $timestamp + * A unix timestamp. + * @param $login + * The user account login name. + * + * @return + * A string that is safe for use in URLs and SQL statements. + */ function user_pass_rehash($password, $timestamp, $login) { return drupal_hmac_base64($timestamp . $login, drupal_get_hash_salt() . $password); } diff --git a/modules/user/user.permissions.js b/modules/user/user.permissions.js index 4ef576cd..988820e1 100644 --- a/modules/user/user.permissions.js +++ b/modules/user/user.permissions.js @@ -5,34 +5,64 @@ */ Drupal.behaviors.permissions = { attach: function (context) { - $('table#permissions:not(.permissions-processed)').each(function () { + var self = this; + $('table#permissions').once('permissions', function () { + // On a site with many roles and permissions, this behavior initially has + // to perform thousands of DOM manipulations to inject checkboxes and hide + // them. By detaching the table from the DOM, all operations can be + // performed without triggering internal layout and re-rendering processes + // in the browser. + var $table = $(this); + if ($table.prev().length) { + var $ancestor = $table.prev(), method = 'after'; + } + else { + var $ancestor = $table.parent(), method = 'append'; + } + $table.detach(); + // Create dummy checkboxes. We use dummy checkboxes instead of reusing // the existing checkboxes here because new checkboxes don't alter the // submitted form. If we'd automatically check existing checkboxes, the // permission table would be polluted with redundant entries. This // is deliberate, but desirable when we automatically check them. - $(':checkbox', this).not('[name^="2["]').not('[name^="1["]').each(function () { - $(this).addClass('real-checkbox'); - $('<input type="checkbox" class="dummy-checkbox" disabled="disabled" checked="checked" />') - .attr('title', Drupal.t("This permission is inherited from the authenticated user role.")) - .insertAfter(this) - .hide(); - }); + var $dummy = $('<input type="checkbox" class="dummy-checkbox" disabled="disabled" checked="checked" />') + .attr('title', Drupal.t("This permission is inherited from the authenticated user role.")) + .hide(); - // Helper function toggles all dummy checkboxes based on the checkboxes' - // state. If the "authenticated user" checkbox is checked, the checked - // and disabled checkboxes are shown, the real checkboxes otherwise. - var toggle = function () { - $(this).closest('tr') - .find('.real-checkbox')[this.checked ? 'hide' : 'show']().end() - .find('.dummy-checkbox')[this.checked ? 'show' : 'hide'](); - }; + $('input[type=checkbox]', this).not('.rid-2, .rid-1').addClass('real-checkbox').each(function () { + $dummy.clone().insertAfter(this); + }); // Initialize the authenticated user checkbox. - $(':checkbox[name^="2["]', this) - .click(toggle) - .each(function () { toggle.call(this); }); - }).addClass('permissions-processed'); + $('input[type=checkbox].rid-2', this) + .bind('click.permissions', self.toggle) + // .triggerHandler() cannot be used here, as it only affects the first + // element. + .each(self.toggle); + + // Re-insert the table into the DOM. + $ancestor[method]($table); + }); + }, + + /** + * Toggles all dummy checkboxes based on the checkboxes' state. + * + * If the "authenticated user" checkbox is checked, the checked and disabled + * checkboxes are shown, the real checkboxes otherwise. + */ + toggle: function () { + var authCheckbox = this, $row = $(this).closest('tr'); + // jQuery performs too many layout calculations for .hide() and .show(), + // leading to a major page rendering lag on sites with many roles and + // permissions. Therefore, we toggle visibility directly. + $row.find('.real-checkbox').each(function () { + this.style.display = (authCheckbox.checked ? 'none' : ''); + }); + $row.find('.dummy-checkbox').each(function () { + this.style.display = (authCheckbox.checked ? '' : 'none'); + }); } }; diff --git a/profiles/minimal/minimal.info b/profiles/minimal/minimal.info index b5b1187a..29311297 100644 --- a/profiles/minimal/minimal.info +++ b/profiles/minimal/minimal.info @@ -6,8 +6,8 @@ dependencies[] = block dependencies[] = dblog files[] = minimal.profile -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/profiles/standard/standard.info b/profiles/standard/standard.info index 9008fea9..daa49faf 100644 --- a/profiles/standard/standard.info +++ b/profiles/standard/standard.info @@ -25,8 +25,8 @@ dependencies[] = file dependencies[] = rdf files[] = standard.profile -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/profiles/standard/standard.install b/profiles/standard/standard.install index 70829064..5d447177 100644 --- a/profiles/standard/standard.install +++ b/profiles/standard/standard.install @@ -327,7 +327,6 @@ function standard_install() { 'field_name' => 'field_image', 'type' => 'image', 'cardinality' => 1, - 'translatable' => TRUE, 'locked' => FALSE, 'indexes' => array('fid' => array('fid')), 'settings' => array( diff --git a/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info b/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info index 52228081..44be97a8 100644 --- a/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info +++ b/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/profiles/testing/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info b/profiles/testing/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info index 277349d7..85ca1bfd 100644 --- a/profiles/testing/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info +++ b/profiles/testing/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info @@ -8,8 +8,8 @@ version = VERSION core = 6.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/profiles/testing/testing.info b/profiles/testing/testing.info index 4f6271c4..6723a104 100644 --- a/profiles/testing/testing.info +++ b/profiles/testing/testing.info @@ -4,8 +4,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/scripts/generate-d6-content.sh b/scripts/generate-d6-content.sh index bba61cae..5079c233 100644 --- a/scripts/generate-d6-content.sh +++ b/scripts/generate-d6-content.sh @@ -100,7 +100,7 @@ module_load_include('inc', 'node', 'node.pages'); for ($i = 0; $i < 24; $i++) { $uid = intval($i / 8) + 3; $user = user_load($uid); - $node = new stdClass; + $node = new stdClass(); $node->uid = $uid; $node->type = $i < 12 ? 'page' : 'story'; $node->sticky = 0; @@ -148,7 +148,7 @@ for ($i = 0; $i < 24; $i++) { for ($i = 0; $i < 12; $i++) { $uid = intval($i / 4) + 3; $user = user_load($uid); - $node = new stdClass; + $node = new stdClass(); $node->uid = $uid; $node->type = 'poll'; $node->sticky = 0; @@ -187,7 +187,7 @@ for ($i = 0; $i < 12; $i++) { $uid = 6; $user = user_load($uid); -$node = new stdClass; +$node = new stdClass(); $node->uid = $uid; $node->type = 'broken'; $node->sticky = 0; diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index db34924c..02e897e4 100755 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -16,10 +16,10 @@ if ($args['help'] || $count == 0) { exit; } -if ($args['execute-batch']) { +if ($args['execute-test']) { // Masquerade as Apache for running tests. simpletest_script_init("Apache"); - simpletest_script_execute_batch(); + simpletest_script_run_one_test($args['test-id'], $args['execute-test']); } else { // Run administrative functions as CLI. @@ -67,8 +67,6 @@ if ($args['list']) { exit; } -$test_list = simpletest_script_get_test_list(); - // Try to allocate unlimited time to run the tests. drupal_set_time_limit(0); @@ -78,7 +76,7 @@ simpletest_script_reporter_init(); $test_id = db_insert('simpletest_test_id')->useDefaults(array('test_id'))->execute(); // Execute tests. -simpletest_script_command($args['concurrency'], $test_id, implode(",", $test_list)); +simpletest_script_execute_batch($test_id, simpletest_script_get_test_list()); // Retrieve the last database prefix used for testing and the last test class // that was run from. Use the information to read the lgo file in case any @@ -99,6 +97,9 @@ if ($args['xml']) { // Cleanup our test results. simpletest_clean_results_table($test_id); +// Test complete, exit. +exit; + /** * Print help text. */ @@ -130,9 +131,7 @@ All arguments are long options. --concurrency [num] - Run tests in parallel, up to [num] tests at a time. This requires - the Process Control Extension (PCNTL) to be compiled in PHP, not - supported under Windows. + Run tests in parallel, up to [num] tests at a time. --all Run all available tests. @@ -193,8 +192,8 @@ function simpletest_script_parse_args() { 'verbose' => FALSE, 'test_names' => array(), // Used internally. - 'test-id' => NULL, - 'execute-batch' => FALSE, + 'test-id' => 0, + 'execute-test' => '', 'xml' => '', ); @@ -236,10 +235,6 @@ function simpletest_script_parse_args() { simpletest_script_print_error("--concurrency must be a strictly positive integer."); exit; } - elseif ($args['concurrency'] > 1 && !function_exists('pcntl_fork')) { - simpletest_script_print_error("Parallel test execution requires the Process Control extension to be compiled in PHP. See http://php.net/manual/en/intro.pcntl.php for more information."); - exit; - } return array($args, $count); } @@ -310,93 +305,96 @@ function simpletest_script_init($server_software) { /** * Execute a batch of tests. */ -function simpletest_script_execute_batch() { +function simpletest_script_execute_batch($test_id, $test_classes) { global $args; - if (!isset($args['test-id'])) { - simpletest_script_print_error("--execute-batch should not be called interactively."); - exit; - } - if ($args['concurrency'] == 1) { - // Fallback to mono-threaded execution. - if (count($args['test_names']) > 1) { - foreach ($args['test_names'] as $test_class) { - // Execute each test in its separate Drupal environment. - simpletest_script_command(1, $args['test-id'], $test_class); + // Multi-process execution. + $children = array(); + while (!empty($test_classes) || !empty($children)) { + while (count($children) < $args['concurrency']) { + if (empty($test_classes)) { + break; } - exit; - } - else { - // Execute an individual test. - $test_class = array_shift($args['test_names']); - drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); - simpletest_script_run_one_test($args['test-id'], $test_class); - exit; - } - } - else { - // Multi-threaded execution. - $children = array(); - while (!empty($args['test_names']) || !empty($children)) { - // Fork children safely since Drupal is not bootstrapped yet. - while (count($children) < $args['concurrency']) { - if (empty($args['test_names'])) break; - - $child = array(); - $child['test_class'] = $test_class = array_shift($args['test_names']); - $child['pid'] = pcntl_fork(); - if (!$child['pid']) { - // This is the child process, bootstrap and execute the test. - drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); - simpletest_script_run_one_test($args['test-id'], $test_class); - exit; - } - else { - // Register our new child. - $children[] = $child; - } + + // Fork a child process. + $test_class = array_shift($test_classes); + $command = simpletest_script_command($test_id, $test_class); + $process = proc_open($command, array(), $pipes, NULL, NULL, array('bypass_shell' => TRUE)); + + if (!is_resource($process)) { + echo "Unable to fork test process. Aborting.\n"; + exit; } - // Wait for children every 200ms. - usleep(200000); + // Register our new child. + $children[] = array( + 'process' => $process, + 'class' => $test_class, + 'pipes' => $pipes, + ); + } - // Check if some children finished. - foreach ($children as $cid => $child) { - if (pcntl_waitpid($child['pid'], $status, WUNTRACED | WNOHANG)) { - // This particular child exited. - unset($children[$cid]); + // Wait for children every 200ms. + usleep(200000); + + // Check if some children finished. + foreach ($children as $cid => $child) { + $status = proc_get_status($child['process']); + if (empty($status['running'])) { + // The child exited, unregister it. + proc_close($child['process']); + if ($status['exitcode']) { + echo 'FATAL ' . $test_class . ': test runner returned a non-zero error code (' . $status['exitcode'] . ').' . "\n"; } + unset($children[$cid]); } } - exit; } } /** - * Run a single test (assume a Drupal bootstrapped environment). + * Bootstrap Drupal and run a single test. */ function simpletest_script_run_one_test($test_id, $test_class) { - $test = new $test_class($test_id); - $test->run(); - $info = $test->getInfo(); + try { + // Bootstrap Drupal. + drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); + + $test = new $test_class($test_id); + $test->run(); + $info = $test->getInfo(); + + $had_fails = (isset($test->results['#fail']) && $test->results['#fail'] > 0); + $had_exceptions = (isset($test->results['#exception']) && $test->results['#exception'] > 0); + $status = ($had_fails || $had_exceptions ? 'fail' : 'pass'); + simpletest_script_print($info['name'] . ' ' . _simpletest_format_summary_line($test->results) . "\n", simpletest_script_color_code($status)); - $status = ((isset($test->results['#fail']) && $test->results['#fail'] > 0) - || (isset($test->results['#exception']) && $test->results['#exception'] > 0) ? 'fail' : 'pass'); - simpletest_script_print($info['name'] . ' ' . _simpletest_format_summary_line($test->results) . "\n", simpletest_script_color_code($status)); + // Finished, kill this runner. + exit(0); + } + catch (Exception $e) { + echo (string) $e; + exit(1); + } } /** - * Execute a command to run batch of tests in separate process. + * Return a command used to run a test in a separate process. + * + * @param $test_id + * The current test ID. + * @param $test_class + * The name of the test class to run. */ -function simpletest_script_command($concurrency, $test_id, $tests) { +function simpletest_script_command($test_id, $test_class) { global $args, $php; - $command = "$php ./scripts/{$args['script']} --url {$args['url']}"; + $command = escapeshellarg($php) . ' ' . escapeshellarg('./scripts/' . $args['script']) . ' --url ' . escapeshellarg($args['url']); if ($args['color']) { $command .= ' --color'; } - $command .= " --php " . escapeshellarg($php) . " --concurrency $concurrency --test-id $test_id --execute-batch $tests"; - passthru($command); + $command .= " --php " . escapeshellarg($php) . " --test-id $test_id --execute-test $test_class"; + return $command; } /** diff --git a/themes/bartik/bartik.info b/themes/bartik/bartik.info index 8ebd6c83..ebfd800d 100644 --- a/themes/bartik/bartik.info +++ b/themes/bartik/bartik.info @@ -34,8 +34,8 @@ regions[footer] = Footer settings[shortcut_module_link] = 0 -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/themes/garland/garland.info b/themes/garland/garland.info index 8e805840..dfcf444f 100644 --- a/themes/garland/garland.info +++ b/themes/garland/garland.info @@ -7,8 +7,8 @@ stylesheets[all][] = style.css stylesheets[print][] = print.css settings[garland_width] = fluid -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/themes/seven/seven.info b/themes/seven/seven.info index de5f3fb6..ac33f5a1 100644 --- a/themes/seven/seven.info +++ b/themes/seven/seven.info @@ -13,8 +13,8 @@ regions[page_bottom] = Page bottom regions[sidebar_first] = First sidebar regions_hidden[] = sidebar_first -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/themes/stark/stark.info b/themes/stark/stark.info index e27d53d6..013eb235 100644 --- a/themes/stark/stark.info +++ b/themes/stark/stark.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x stylesheets[all][] = layout.css -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/themes/tests/test_theme/test_theme.info b/themes/tests/test_theme/test_theme.info index 0a791d48..7af270df 100644 --- a/themes/tests/test_theme/test_theme.info +++ b/themes/tests/test_theme/test_theme.info @@ -15,8 +15,8 @@ hidden = TRUE ; file within the theme folder. stylesheets[all][] = system.base.css -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/themes/tests/update_test_basetheme/update_test_basetheme.info b/themes/tests/update_test_basetheme/update_test_basetheme.info index cc800fa8..f2e43a2c 100644 --- a/themes/tests/update_test_basetheme/update_test_basetheme.info +++ b/themes/tests/update_test_basetheme/update_test_basetheme.info @@ -3,8 +3,8 @@ description = Test theme which acts as a base theme for other test subthemes. core = 7.x hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" diff --git a/themes/tests/update_test_subtheme/update_test_subtheme.info b/themes/tests/update_test_subtheme/update_test_subtheme.info index 0265dc54..e5e4c46f 100644 --- a/themes/tests/update_test_subtheme/update_test_subtheme.info +++ b/themes/tests/update_test_subtheme/update_test_subtheme.info @@ -4,8 +4,8 @@ core = 7.x base theme = update_test_basetheme hidden = TRUE -; Information added by drupal.org packaging script on 2011-06-30 -version = "7.4" +; Information added by drupal.org packaging script on 2011-07-28 +version = "7.7" project = "drupal" -datestamp = "1309397516" +datestamp = "1311813879" -- GitLab