From 5658794f1795817590d5db89ac416d76ea1ba900 Mon Sep 17 00:00:00 2001 From: bachy Date: Fri, 24 May 2013 13:03:57 +0200 Subject: [PATCH] update to 7.22 Signed-off-by: bachy --- CHANGELOG.txt | 67 + authorize.php | 35 +- includes/ajax.inc | 7 +- includes/bootstrap.inc | 54 +- includes/cache.inc | 69 +- includes/common.inc | 40 +- includes/database/database.inc | 43 +- includes/database/mysql/database.inc | 17 +- includes/database/query.inc | 9 +- includes/database/sqlite/query.inc | 27 +- includes/entity.inc | 12 - includes/file.inc | 25 +- includes/filetransfer/filetransfer.inc | 10 + includes/form.inc | 34 +- includes/image.inc | 8 +- includes/install.core.inc | 33 +- includes/install.inc | 6 + includes/language.inc | 179 +- includes/mail.inc | 28 +- includes/menu.inc | 1 + includes/module.inc | 17 +- includes/password.inc | 2 +- includes/path.inc | 12 +- includes/session.inc | 2 +- includes/tablesort.inc | 16 +- includes/theme.inc | 151 +- includes/theme.maintenance.inc | 10 +- includes/token.inc | 18 +- includes/unicode.inc | 135 +- includes/update.inc | 12 +- includes/utility.inc | 1 + install.php | 4 +- misc/ajax.js | 2 +- misc/autocomplete.js | 5 +- misc/machine-name.js | 2 +- misc/tableheader.js | 2 +- modules/aggregator/aggregator-rtl.css | 3 + modules/aggregator/aggregator.admin.inc | 14 +- modules/aggregator/aggregator.css | 3 + modules/aggregator/aggregator.info | 6 +- modules/aggregator/aggregator.module | 10 +- modules/aggregator/aggregator.pages.inc | 69 +- modules/aggregator/aggregator.processor.inc | 6 + modules/aggregator/aggregator.test | 119 +- modules/aggregator/tests/aggregator_test.info | 6 +- modules/block/block.info | 6 +- modules/block/block.module | 2 +- modules/block/tests/block_test.info | 6 +- .../block_test_theme/block_test_theme.info | 6 +- modules/blog/blog.info | 6 +- modules/book/book-rtl.css | 4 + modules/book/book.admin.inc | 15 +- modules/book/book.css | 4 + modules/book/book.info | 6 +- modules/book/book.js | 1 - modules/book/book.module | 47 +- modules/book/book.pages.inc | 13 +- modules/book/book.test | 121 +- modules/color/color.info | 6 +- modules/comment/comment.admin.inc | 3 +- modules/comment/comment.info | 6 +- modules/comment/comment.module | 20 +- modules/contact/contact.info | 6 +- modules/contextual/contextual.info | 6 +- modules/dashboard/dashboard.info | 6 +- modules/dblog/dblog-rtl.css | 4 + modules/dblog/dblog.admin.inc | 79 +- modules/dblog/dblog.css | 5 + modules/dblog/dblog.info | 6 +- modules/dblog/dblog.install | 17 + modules/dblog/dblog.module | 18 +- modules/dblog/dblog.test | 228 +- modules/field/field.api.php | 9 +- modules/field/field.attach.inc | 83 +- modules/field/field.crud.inc | 19 +- modules/field/field.info | 7 +- modules/field/field.info.class.inc | 668 +++ modules/field/field.info.inc | 449 +- modules/field/field.install | 7 + modules/field/field.module | 5 +- .../field_sql_storage/field_sql_storage.info | 6 +- .../field_sql_storage.module | 7 +- modules/field/modules/list/list.info | 6 +- .../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/tests/field.test | 354 +- modules/field/tests/field_test.entity.inc | 6 + modules/field/tests/field_test.info | 6 +- modules/field_ui/field_ui.admin.inc | 4 +- modules/field_ui/field_ui.info | 6 +- modules/field_ui/field_ui.module | 23 +- modules/field_ui/field_ui.test | 6 +- modules/file/file.field.inc | 12 +- modules/file/file.info | 6 +- modules/file/tests/file_module_test.info | 6 +- modules/filter/filter.admin.inc | 65 +- modules/filter/filter.info | 6 +- modules/filter/filter.install | 2 +- modules/filter/filter.module | 225 +- modules/filter/filter.pages.inc | 14 +- modules/filter/filter.test | 118 +- modules/forum/forum-rtl.css | 4 + modules/forum/forum.css | 2 +- modules/forum/forum.info | 6 +- modules/forum/forum.module | 7 +- modules/forum/forum.test | 1 + modules/help/help.info | 6 +- modules/image/image.admin.inc | 2 +- modules/image/image.info | 6 +- modules/image/image.install | 3 +- modules/image/image.module | 92 +- modules/image/image.test | 25 +- modules/image/tests/image_module_test.info | 6 +- modules/locale/locale.admin.inc | 4 +- modules/locale/locale.info | 6 +- modules/locale/locale.module | 66 +- modules/locale/locale.test | 42 +- modules/locale/tests/locale_test.info | 6 +- modules/menu/menu.admin.inc | 2 +- modules/menu/menu.api.php | 8 +- modules/menu/menu.info | 6 +- modules/menu/menu.test | 2 +- modules/node/content_types.inc | 9 +- modules/node/node.admin.inc | 135 +- modules/node/node.api.php | 200 +- modules/node/node.info | 6 +- modules/node/node.install | 2 + modules/node/node.module | 399 +- modules/node/node.pages.inc | 107 +- modules/node/node.test | 160 +- modules/node/tests/node_access_test.info | 6 +- modules/node/tests/node_access_test.module | 6 +- modules/node/tests/node_test.info | 6 +- modules/node/tests/node_test.module | 6 +- modules/node/tests/node_test_exception.info | 6 +- modules/node/tests/node_test_exception.module | 3 +- modules/openid/openid.info | 6 +- modules/openid/openid.module | 16 +- modules/openid/tests/openid_test.info | 6 +- modules/overlay/overlay-parent.js | 7 +- modules/overlay/overlay.info | 6 +- modules/overlay/overlay.module | 2 +- modules/path/path.info | 6 +- modules/php/php.info | 6 +- modules/php/php.module | 2 +- modules/poll/poll.info | 6 +- modules/profile/profile.info | 6 +- modules/rdf/rdf.info | 6 +- modules/rdf/rdf.module | 9 +- modules/rdf/rdf.test | 126 +- modules/rdf/tests/rdf_test.info | 6 +- modules/search/search.info | 6 +- modules/search/search.pages.inc | 1 - .../search/tests/search_embedded_form.info | 6 +- modules/search/tests/search_extra_type.info | 6 +- modules/shortcut/shortcut.info | 6 +- modules/simpletest/drupal_web_test_case.php | 62 +- .../Drupal/simpletest/Tests/PSR0WebTest.php | 18 + modules/simpletest/simpletest.info | 6 +- modules/simpletest/simpletest.module | 107 + modules/simpletest/simpletest.pages.inc | 3 + modules/simpletest/simpletest.test | 159 +- .../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 | 24 +- modules/simpletest/tests/common_test.info | 6 +- .../tests/common_test_cron_helper.info | 6 +- modules/simpletest/tests/database_test.info | 6 +- modules/simpletest/tests/database_test.test | 962 ++-- ...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 +- .../tests/entity_query_access_test.info | 6 +- modules/simpletest/tests/error_test.info | 6 +- modules/simpletest/tests/file.test | 9 + modules/simpletest/tests/file_test.info | 6 +- modules/simpletest/tests/filter_test.info | 6 +- modules/simpletest/tests/form.test | 11 + modules/simpletest/tests/form_test.info | 6 +- modules/simpletest/tests/image_test.info | 6 +- modules/simpletest/tests/menu_test.info | 6 +- modules/simpletest/tests/module_test.info | 6 +- modules/simpletest/tests/path_test.info | 6 +- .../Drupal/psr_0_test/Tests/ExampleTest.php | 18 + .../Tests/Nested/NestedExampleTest.php | 18 + .../tests/psr_0_test/psr_0_test.info | 12 + .../tests/psr_0_test/psr_0_test.module | 1 + .../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 +- ...atible_core_version_dependencies_test.info | 6 +- ...system_incompatible_core_version_test.info | 6 +- ...ible_module_version_dependencies_test.info | 6 +- ...stem_incompatible_module_version_test.info | 6 +- modules/simpletest/tests/system_test.info | 6 +- modules/simpletest/tests/taxonomy_test.info | 6 +- modules/simpletest/tests/theme_test.info | 6 +- .../themes/test_basetheme/test_basetheme.info | 6 +- .../themes/test_subtheme/test_subtheme.info | 6 +- .../tests/themes/test_theme/test_theme.info | 6 +- .../simpletest/tests/update_script_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 +- ...drupal-6.duplicate-permission.database.php | 8 + modules/simpletest/tests/upgrade/upgrade.test | 14 + .../tests/upgrade/upgrade.user.test | 29 + 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/language.api.php | 86 +- modules/system/system.admin.inc | 6 + modules/system/system.api.php | 64 +- modules/system/system.info | 6 +- modules/system/system.install | 34 +- modules/system/system.module | 23 +- modules/system/system.test | 31 + modules/system/system.updater.inc | 4 + modules/taxonomy/taxonomy-term.tpl.php | 3 +- modules/taxonomy/taxonomy.info | 6 +- modules/taxonomy/taxonomy.pages.inc | 5 +- modules/taxonomy/taxonomy.test | 7 + modules/toolbar/toolbar.info | 6 +- modules/tracker/tracker.info | 6 +- .../translation/tests/translation_test.info | 6 +- modules/translation/translation.info | 6 +- 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 +- .../update_test_basetheme.info | 6 +- .../update_test_subtheme.info | 6 +- modules/update/tests/update_test.info | 6 +- modules/update/update.info | 6 +- modules/update/update.module | 6 +- modules/user/tests/user_form_test.info | 6 +- modules/user/user.admin.inc | 15 + modules/user/user.api.php | 6 +- modules/user/user.info | 6 +- modules/user/user.module | 58 +- modules/user/user.module.orig | 3967 ----------------- modules/user/user.pages.inc | 2 +- modules/user/user.test | 53 - modules/user/user.test.orig | 2348 ---------- profiles/minimal/minimal.info | 6 +- profiles/standard/standard.info | 6 +- ...drupal_system_listing_compatible_test.info | 6 +- ...upal_system_listing_incompatible_test.info | 6 +- profiles/testing/testing.info | 6 +- scripts/run-tests.sh | 4 +- themes/bartik/bartik.info | 6 +- themes/garland/garland.info | 6 +- themes/seven/seven.info | 6 +- themes/seven/template.php | 3 + themes/stark/stark.info | 6 +- update.php | 38 +- 265 files changed, 5551 insertions(+), 8808 deletions(-) create mode 100644 modules/field/field.info.class.inc create mode 100644 modules/simpletest/lib/Drupal/simpletest/Tests/PSR0WebTest.php create mode 100644 modules/simpletest/tests/psr_0_test/lib/Drupal/psr_0_test/Tests/ExampleTest.php create mode 100644 modules/simpletest/tests/psr_0_test/lib/Drupal/psr_0_test/Tests/Nested/NestedExampleTest.php create mode 100644 modules/simpletest/tests/psr_0_test/psr_0_test.info create mode 100644 modules/simpletest/tests/psr_0_test/psr_0_test.module create mode 100644 modules/simpletest/tests/upgrade/drupal-6.duplicate-permission.database.php delete mode 100644 modules/user/user.module.orig delete mode 100644 modules/user/user.test.orig diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 69d94de7..5b655b8b 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,4 +1,71 @@ +Drupal 7.22, 2013-04-03 +----------------------- +- Allowed the drupal_http_request() function to be overridden so that + additional HTTP request capabilities can be added by contributed modules. +- Changed the Simpletest module to allow PSR-0 test classes to be used in + Drupal 7. +- Removed an unnecessary "Content-Disposition" header from private file + downloads; it prevented many private files from being viewed inline in a web + browser. +- Changed various field API functions to allow them to optionally act on a + single field within an entity (API addition: http://drupal.org/node/1825844). +- Fixed a bug which prevented Drupal's file transfer functionality from working + on some PHP 5.4 systems. +- Fixed incorrect log message when theme() is called for a theme hook that does + not exist (minor string change). +- Fixed Drupal's token-replacement system to allow spaces in the token value. +- Changed the default behavior after a user creates a node they do not have + access to view. The user will now be redirected to the front page rather than + an access denied page. +- Fixed a bug which prevented empty HTTP headers (such as "0") from being set. + (Minor behavior change: Callers of drupal_add_http_header() must now set + FALSE explicitly to prevent a header from being sent at all; this was already + indicated in the function's documentation.) +- Fixed OpenID errors when more than one module implements hook_openid(). The + behavior is now changed so that if more than one module tries to set the same + parameter, the last module's change takes effect. +- Fixed a serious documentation bug: The $name variable in the + taxonomy-term.tpl.php theme template was incorrectly documented as being + sanitized when in fact it is not. +- Fixed a bug which prevented Drupal 6 to Drupal 7 upgrades on sites which had + duplicate permission names in the User module's database tables. +- Added an empty "datatype" attribute to taxonomy term and username links to + make the RDFa markup upward compatible with RDFa 1.1 (minor markup addition). +- Fixed a bug which caused the denial-of-service protection added in Drupal + 7.20 to break certain valid image URLs that had an extra slash in them. +- Fixed a bug with update queries in the SQLite database driver that prevented + Drupal from being installed with SQLite on PHP 5.4. +- Fixed enforced dependencies errors updating to recent versions of Drupal 7 on + certain non-MySQL databases. +- Refactored the Field module's caching behavior to obtain large improvements + in memory usage for sites with many fields and instances (API addition: + http://drupal.org/node/1915646). +- Fixed entity argument not being passed to implementations of + hook_file_download_access_alter(). The fix adds an additional context + parameter that can be passed when calling drupal_alter() for any hook (API + change: http://drupal.org/node/1882722). +- Fixed broken support for translatable comment fields (API change: + http://drupal.org/node/1874724). +- Added an assertThemeOutput() method to Simpletest to allow tests to check + that themed output matches an expected HTML string (API addition). +- Added a link to "Install another module" after a module has been successfully + downloaded via the Update Manager (UI change). +- Added an optional "exclusive" flag to installation profile .info files which + allows Drupal distributions to force a profile to be selected during + installation (API addition). +- Fixed a bug which caused the database API to not properly close database + connections. +- Added a link to the URL for running cron from outside the site to the Cron + settings page (UI change). +- Fixed a bug which prevented image styles from being reverted on PHP 5.4. +- Made the default .htaccess rules protocol sensitive to improve security for + sites which use HTTPS and redirect between "www" and non-"www" versions of + the page. +- Numerous small bug fixes. +- Numerous API documentation improvements. +- Additional automated test coverage. + Drupal 7.21, 2013-03-06 ----------------------- - Allowed sites using the 'image_allow_insecure_derivatives' variable to still diff --git a/authorize.php b/authorize.php index d14fa6e5..3ea2b20a 100644 --- a/authorize.php +++ b/authorize.php @@ -4,16 +4,16 @@ * @file * Administrative script for running authorized file operations. * - * Using this script, the site owner (the user actually owning the files on - * the webserver) can authorize certain file-related operations to proceed - * with elevated privileges, for example to deploy and upgrade modules or - * themes. Users should not visit this page directly, but instead use an - * administrative user interface which knows how to redirect the user to this - * script as part of a multistep process. This script actually performs the - * selected operations without loading all of Drupal, to be able to more - * gracefully recover from errors. Access to the script is controlled by a - * global killswitch in settings.php ('allow_authorize_operations') and via - * the 'administer software updates' permission. + * Using this script, the site owner (the user actually owning the files on the + * webserver) can authorize certain file-related operations to proceed with + * elevated privileges, for example to deploy and upgrade modules or themes. + * Users should not visit this page directly, but instead use an administrative + * user interface which knows how to redirect the user to this script as part of + * a multistep process. This script actually performs the selected operations + * without loading all of Drupal, to be able to more gracefully recover from + * errors. Access to the script is controlled by a global killswitch in + * settings.php ('allow_authorize_operations') and via the 'administer software + * updates' permission. * * There are helper functions for setting up an operation to run via this * system in modules/system/system.module. For more information, see: @@ -21,16 +21,17 @@ */ /** - * Root directory of Drupal installation. + * Defines the root directory of the Drupal installation. */ define('DRUPAL_ROOT', getcwd()); /** - * Global flag to identify update.php and authorize.php runs, and so - * avoid various unwanted operations, such as hook_init() and - * hook_exit() invokes, css/js preprocessing and translation, and - * solve some theming issues. This flag is checked on several places - * in Drupal code (not just authorize.php). + * Global flag to identify update.php and authorize.php runs. + * + * Identifies update.php and authorize.php runs, avoiding unwanted operations + * such as hook_init() and hook_exit() invokes, css/js preprocessing and + * translation, and solves some theming issues. The flag is checked in other + * places in Drupal code (not just authorize.php). */ define('MAINTENANCE_MODE', 'update'); @@ -51,7 +52,7 @@ function authorize_access_denied_page() { * have access to the 'administer software updates' permission. * * @return - * TRUE if the current user can run authorize.php, otherwise FALSE. + * TRUE if the current user can run authorize.php, and FALSE if not. */ function authorize_access_allowed() { return variable_get('allow_authorize_operations', TRUE) && user_access('administer software updates'); diff --git a/includes/ajax.inc b/includes/ajax.inc index 4107029f..ab0111ce 100644 --- a/includes/ajax.inc +++ b/includes/ajax.inc @@ -251,8 +251,8 @@ function ajax_render($commands = array()) { // reliably diffed with array_diff_key(), since the number can change // due to factors unrelated to the inline content, so for now, we strip // the inline items from Ajax responses, and can add support for them - // when drupal_add_css() and drupal_add_js() are changed to using md5() - // or some other hash of the inline content. + // when drupal_add_css() and drupal_add_js() are changed to use a hash + // of the inline content as the array key. foreach ($items[$type] as $key => $item) { if (is_numeric($key)) { unset($items[$type][$key]); @@ -836,7 +836,8 @@ function ajax_command_insert($selector, $html, $settings = NULL) { * @return * An array suitable for use with the ajax_render() function. * - * See @link http://docs.jquery.com/Manipulation/replaceWith#content jQuery replaceWith command @endlink + * See + * @link http://docs.jquery.com/Manipulation/replaceWith#content jQuery replaceWith command @endlink */ function ajax_command_replace($selector, $html, $settings = NULL) { return array( diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index 93322de4..728e4ec2 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -8,7 +8,7 @@ /** * The current system version. */ -define('VERSION', '7.21'); +define('VERSION', '7.22'); /** * Core API compatibility. @@ -716,7 +716,6 @@ function drupal_settings_initialize() { if (isset($base_url)) { // Parse fixed base URL from settings.php. $parts = parse_url($base_url); - $http_protocol = $parts['scheme']; if (!isset($parts['path'])) { $parts['path'] = ''; } @@ -811,7 +810,7 @@ function drupal_settings_initialize() { * than by consulting the database. * * @return - * The filename of the requested item. + * The filename of the requested item or NULL if the item is not found. */ function drupal_get_filename($type, $name, $filename = NULL) { // The location of files will not change during the request, so do not use @@ -1186,10 +1185,11 @@ function _drupal_set_preferred_header_name($name = NULL) { * Headers are set in drupal_add_http_header(). Default headers are not set * if they have been replaced or unset using drupal_add_http_header(). * - * @param $default_headers - * An array of headers as name/value pairs. - * @param $single - * If TRUE and headers have already be sent, send only the specified header. + * @param array $default_headers + * (optional) An array of headers as name/value pairs. + * @param bool $only_default + * (optional) If TRUE and headers have already been sent, send only the + * specified headers. */ function drupal_send_headers($default_headers = array(), $only_default = FALSE) { $headers_sent = &drupal_static(__FUNCTION__, FALSE); @@ -1212,7 +1212,7 @@ function drupal_send_headers($default_headers = array(), $only_default = FALSE) header($_SERVER['SERVER_PROTOCOL'] . ' ' . $value); } // Skip headers that have been unset. - elseif ($value) { + elseif ($value !== FALSE) { header($header_names[$name_lower] . ': ' . $value); } } @@ -1420,8 +1420,9 @@ function drupal_unpack($obj, $field = 'data') { * Basically, you can put variables like @name into your string, and t() will * substitute their sanitized values at translation time. (See the * Localization API pages referenced above and the documentation of - * format_string() for details.) Translators can then rearrange the string as - * necessary for the language (e.g., in Spanish, it might be "blog de @name"). + * format_string() for details about how to define variables in your string.) + * Translators can then rearrange the string as necessary for the language + * (e.g., in Spanish, it might be "blog de @name"). * * During the Drupal installation phase, some resources used by t() wil not be * available to code that needs localization. See st() and get_t() for @@ -1484,21 +1485,34 @@ function t($string, array $args = array(), array $options = array()) { } /** - * Replaces placeholders with sanitized values in a string. + * Formats a string for HTML display by replacing variable placeholders. + * + * This function replaces variable placeholders in a string with the requested + * values and escapes the values so they can be safely displayed as HTML. It + * should be used on any unknown text that is intended to be printed to an HTML + * page (especially text that may have come from untrusted users, since in that + * case it prevents cross-site scripting and other security problems). + * + * In most cases, you should use t() rather than calling this function + * directly, since it will translate the text (on non-English-only sites) in + * addition to formatting it. * * @param $string * A string containing placeholders. * @param $args * An associative array of replacements to make. Occurrences in $string of - * any key in $args are replaced with the corresponding value, after - * sanitization. The sanitization function depends on the first character of - * the key: - * - !variable: Inserted as is. Use this for text that has already been - * sanitized. - * - @variable: Escaped to HTML using check_plain(). Use this for anything - * displayed on a page on the site. - * - %variable: Escaped as a placeholder for user-submitted content using - * drupal_placeholder(), which shows up as emphasized text. + * any key in $args are replaced with the corresponding value, after optional + * sanitization and formatting. The type of sanitization and formatting + * depends on the first character of the key: + * - @variable: Escaped to HTML using check_plain(). Use this as the default + * choice for anything displayed on a page on the site. + * - %variable: Escaped to HTML and formatted using drupal_placeholder(), + * which makes it display as emphasized text. + * - !variable: Inserted as is, with no sanitization or formatting. Only use + * this for text that has already been prepared for HTML display (for + * example, user-supplied text that has already been run through + * check_plain() previously, or is expected to contain some limited HTML + * tags and has already been run through filter_xss() previously). * * @see t() * @ingroup sanitization diff --git a/includes/cache.inc b/includes/cache.inc index a19d3c38..f76164b9 100644 --- a/includes/cache.inc +++ b/includes/cache.inc @@ -80,43 +80,15 @@ function cache_get_multiple(array &$cids, $bin = 'cache') { * same name. Other implementations might want to store several bins in data * structures that get flushed together. While it is not a problem for most * cache bins if the entries in them are flushed before their expire time, some - * might break functionality or are extremely expensive to recalculate. These - * will be marked with a (*). The other bins expired automatically by core. - * Contributed modules can add additional bins and get them expired - * automatically by implementing hook_flush_caches(). - * - * - cache: Generic cache storage bin (used for variables, theme registry, - * locale date, list of simpletest tests etc). - * - * - cache_block: Stores the content of various blocks. - * - * - cache field: Stores the field data belonging to a given object. - * - * - cache_filter: Stores filtered pieces of content. - * - * - cache_form(*): Stores multistep forms. Flushing this bin means that some - * forms displayed to users lose their state and the data already submitted - * to them. - * - * - cache_menu: Stores the structure of visible navigation menus per page. - * - * - cache_page: Stores generated pages for anonymous users. It is flushed - * very often, whenever a page changes, at least for every ode and comment - * submission. This is the only bin affected by the page cache setting on - * the administrator panel. - * - * - cache path: Stores the system paths that have an alias. - * - * - cache update(*): Stores available releases. The update server (for - * example, drupal.org) needs to produce the relevant XML for every project - * installed on the current site. As this is different for (almost) every - * site, it's very expensive to recalculate for the update server. + * might break functionality or are extremely expensive to recalculate. The + * other bins are expired automatically by core. Contributed modules can add + * additional bins and get them expired automatically by implementing + * hook_flush_caches(). * * The reasons for having several bins are as follows: - * - * - smaller bins mean smaller database tables and allow for faster selects and - * inserts - * - we try to put fast changing cache items and rather static ones into + * - Smaller bins mean smaller database tables and allow for faster selects and + * inserts. + * - We try to put fast changing cache items and rather static ones into * different bins. The effect is that only the fast changing bins will need a * lot of writes to disk. The more static bins will also be better cacheable * with MySQL's query cache. @@ -125,13 +97,27 @@ function cache_get_multiple(array &$cids, $bin = 'cache') { * The cache ID of the data to store. * @param $data * The data to store in the cache. Complex data types will be automatically - * serialized before insertion. - * Strings will be stored as plain text and not serialized. + * serialized before insertion. Strings will be stored as plain text and are + * not serialized. * @param $bin - * The cache bin to store the data in. Valid core values are 'cache_block', - * 'cache_bootstrap', 'cache_field', 'cache_filter', 'cache_form', - * 'cache_menu', 'cache_page', 'cache_update' or 'cache' for the default - * cache. + * The cache bin to store the data in. Valid core values are: + * - cache: (default) Generic cache storage bin (used for theme registry, + * locale date, list of simpletest tests, etc.). + * - cache_block: Stores the content of various blocks. + * - cache_bootstrap: Stores the class registry, the system list of modules, + * the list of which modules implement which hooks, and the Drupal variable + * list. + * - cache_field: Stores the field data belonging to a given object. + * - cache_filter: Stores filtered pieces of content. + * - cache_form: Stores multistep forms. Flushing this bin means that some + * forms displayed to users lose their state and the data already submitted + * to them. This bin should not be flushed before its expired time. + * - cache_menu: Stores the structure of visible navigation menus per page. + * - cache_page: Stores generated pages for anonymous users. It is flushed + * very often, whenever a page changes, at least for every node and comment + * submission. This is the only bin affected by the page cache setting on + * the administrator panel. + * - cache_path: Stores the system paths that have an alias. * @param $expire * One of the following values: * - CACHE_PERMANENT: Indicates that the item should never be removed unless @@ -141,6 +127,7 @@ function cache_get_multiple(array &$cids, $bin = 'cache') { * - A Unix timestamp: Indicates that the item should be kept at least until * the given time, after which it behaves like CACHE_TEMPORARY. * + * @see _update_cache_set() * @see cache_get() */ function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) { diff --git a/includes/common.inc b/includes/common.inc index 8276576e..27fa190e 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -281,7 +281,7 @@ function drupal_get_rdf_namespaces() { /** * Adds output to the HEAD tag of the HTML page. * - * This function can be called as long the headers aren't sent. Pass no + * This function can be called as long as the headers aren't sent. Pass no * arguments (or NULL for both) to retrieve the currently stored elements. * * @param $data @@ -785,6 +785,13 @@ function drupal_access_denied() { * - data: A string containing the response body that was received. */ function drupal_http_request($url, array $options = array()) { + // Allow an alternate HTTP client library to replace Drupal's default + // implementation. + $override_function = variable_get('drupal_http_request_function', FALSE); + if (!empty($override_function) && function_exists($override_function)) { + return $override_function($url, $options); + } + $result = new stdClass(); // Parse the URL and make sure we can handle the schema. @@ -1167,7 +1174,8 @@ function fix_gpc_magic() { /** * Verifies the syntax of the given e-mail address. * - * See @link http://tools.ietf.org/html/rfc5321 RFC 5321 @endlink for details. + * This uses the + * @link http://php.net/manual/filter.filters.validate.php PHP e-mail validation filter. @endlink * * @param $mail * A string containing an e-mail address. @@ -2379,6 +2387,14 @@ function drupal_attributes(array $attributes = array()) { * internal links output by modules should be generated by this function if * possible. * + * However, for links enclosed in translatable text you should use t() and + * embed the HTML anchor tag directly in the translated string. For example: + * @code + * t('Visit the settings page', array('@url' => url('admin'))); + * @endcode + * This keeps the context of the link title ('settings' in the example) for + * translators. + * * @param string $text * The translated link text for the anchor tag. * @param string $path @@ -2779,7 +2795,7 @@ function drupal_set_time_limit($time_limit) { * The name of the item for which the path is requested. * * @return - * The path to the requested item. + * The path to the requested item or an empty string if the item is not found. */ function drupal_get_path($type, $name) { return dirname(drupal_get_filename($type, $name)); @@ -3869,7 +3885,16 @@ function drupal_html_id($id) { // requested id. $_POST['ajax_html_ids'] contains the ids as they were // returned by this function, potentially with the appended counter, so // we parse that to reconstruct the $seen_ids array. - foreach ($_POST['ajax_html_ids'] as $seen_id) { + if (is_array($_POST['ajax_html_ids'])) { + $ajax_html_ids = $_POST['ajax_html_ids']; + } + else { + // jquery.form.js may send the server a comma-separated string instead + // of an array (see http://drupal.org/node/1575060), so we need to + // convert it to an array in that case. + $ajax_html_ids = explode(',', $_POST['ajax_html_ids']); + } + foreach ($ajax_html_ids as $seen_id) { // We rely on '--' being used solely for separating a base id from the // counter, which this function ensures when returning an id. $parts = explode('--', $seen_id, 2); @@ -5038,6 +5063,11 @@ function drupal_get_private_key() { * * @param $value * An additional value to base the token on. + * + * @return string + * A 43-character URL-safe token for validation, based on the user session ID, + * the global $drupal_hash_salt variable from settings.php, and the + * 'drupal_private_key' configuration variable. */ function drupal_get_token($value = '') { return drupal_hmac_base64($value, session_id() . drupal_get_private_key() . drupal_get_hash_salt()); @@ -5568,7 +5598,7 @@ function drupal_pre_render_link($element) { * @code * $node->content['links'] = array( * '#theme' => 'links__node', - * '#pre_render' = array('drupal_pre_render_links'), + * '#pre_render' => array('drupal_pre_render_links'), * 'comment' => array( * '#theme' => 'links__node__comment', * '#links' => array( diff --git a/includes/database/database.inc b/includes/database/database.inc index cae50fb8..339c9b03 100644 --- a/includes/database/database.inc +++ b/includes/database/database.inc @@ -167,7 +167,7 @@ * } * @endcode * - * @link http://drupal.org/developing/api/database @endlink + * @see http://drupal.org/developing/api/database */ @@ -194,7 +194,7 @@ abstract class DatabaseConnection extends PDO { /** * The key representing this connection. - * + * * The key is a unique string which identifies a database connection. A * connection can be a single server or a cluster of master and slaves (use * target to pick between master and slave). @@ -303,12 +303,28 @@ abstract class DatabaseConnection extends PDO { // Call PDO::__construct and PDO::setAttribute. parent::__construct($dsn, $username, $password, $driver_options); - // Set a specific PDOStatement class if the driver requires that. + // Set a Statement class, unless the driver opted out. if (!empty($this->statementClass)) { $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array($this->statementClass, array($this))); } } + /** + * Destroys this Connection object. + * + * PHP does not destruct an object if it is still referenced in other + * variables. In case of PDO database connection objects, PHP only closes the + * connection when the PDO object is destructed, so any references to this + * object may cause the number of maximum allowed connections to be exceeded. + */ + public function destroy() { + // Destroy all references to this connection by setting them to NULL. + // The Statement class attribute only accepts a new value that presents a + // proper callable, so we reset it to PDOStatement. + $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('PDOStatement', array())); + $this->schema = NULL; + } + /** * Returns the default query options for any given query. * @@ -1627,8 +1643,8 @@ abstract class Database { */ final public static function removeConnection($key) { if (isset(self::$databaseInfo[$key])) { + self::closeConnection(NULL, $key); unset(self::$databaseInfo[$key]); - unset(self::$connections[$key]); return TRUE; } else { @@ -1694,11 +1710,24 @@ abstract class Database { if (!isset($key)) { $key = self::$activeKey; } - // To close the connection, we need to unset the static variable. + // To close a connection, it needs to be set to NULL and removed from the + // static variable. In all cases, closeConnection() might be called for a + // connection that was not opened yet, in which case the key is not defined + // yet and we just ensure that the connection key is undefined. if (isset($target)) { + if (isset(self::$connections[$key][$target])) { + self::$connections[$key][$target]->destroy(); + self::$connections[$key][$target] = NULL; + } unset(self::$connections[$key][$target]); } else { + if (isset(self::$connections[$key])) { + foreach (self::$connections[$key] as $target => $connection) { + self::$connections[$key][$target]->destroy(); + self::$connections[$key][$target] = NULL; + } + } unset(self::$connections[$key]); } } @@ -1852,8 +1881,8 @@ class DatabaseTransaction { */ protected $name; - public function __construct(DatabaseConnection &$connection, $name = NULL) { - $this->connection = &$connection; + public function __construct(DatabaseConnection $connection, $name = NULL) { + $this->connection = $connection; // If there is no transaction depth, then no transaction has started. Name // the transaction 'drupal_transaction'. if (!$depth = $connection->transactionDepth()) { diff --git a/includes/database/mysql/database.inc b/includes/database/mysql/database.inc index 7ad019e5..00d81f47 100644 --- a/includes/database/mysql/database.inc +++ b/includes/database/mysql/database.inc @@ -13,11 +13,11 @@ class DatabaseConnection_mysql extends DatabaseConnection { /** - * Flag to indicate if we have registered the nextID cleanup function. + * Flag to indicate if the cleanup function in __destruct() should run. * * @var boolean */ - protected $shutdownRegistered = FALSE; + protected $needsCleanup = FALSE; public function __construct(array $connection_options = array()) { // This driver defaults to transaction support, except if explicitly passed FALSE. @@ -78,6 +78,12 @@ class DatabaseConnection_mysql extends DatabaseConnection { $this->exec(implode('; ', $connection_options['init_commands'])); } + public function __destruct() { + if ($this->needsCleanup) { + $this->nextIdDelete(); + } + } + public function queryRange($query, $from, $count, array $args = array(), array $options = array()) { return $this->query($query . ' LIMIT ' . (int) $from . ', ' . (int) $count, $args, $options); } @@ -115,12 +121,7 @@ class DatabaseConnection_mysql extends DatabaseConnection { $this->query('INSERT INTO {sequences} (value) VALUES (:value) ON DUPLICATE KEY UPDATE value = value', array(':value' => $existing_id)); $new_id = $this->query('INSERT INTO {sequences} () VALUES ()', array(), array('return' => Database::RETURN_INSERT_ID)); } - if (!$this->shutdownRegistered) { - // Use register_shutdown_function() here to keep the database system - // independent of Drupal. - register_shutdown_function(array($this, 'nextIdDelete')); - $shutdownRegistered = TRUE; - } + $this->needsCleanup = TRUE; return $new_id; } diff --git a/includes/database/query.inc b/includes/database/query.inc index 612985e0..8beeef1e 100644 --- a/includes/database/query.inc +++ b/includes/database/query.inc @@ -1898,8 +1898,13 @@ class DatabaseCondition implements QueryConditionInterface, Countable { function __clone() { $this->changed = TRUE; foreach ($this->conditions as $key => $condition) { - if ($key !== '#conjunction' && $condition['field'] instanceOf QueryConditionInterface) { - $this->conditions[$key]['field'] = clone($condition['field']); + if ($key !== '#conjunction') { + if ($condition['field'] instanceOf QueryConditionInterface) { + $this->conditions[$key]['field'] = clone($condition['field']); + } + if ($condition['value'] instanceOf SelectQueryInterface) { + $this->conditions[$key]['value'] = clone($condition['value']); + } } } } diff --git a/includes/database/sqlite/query.inc b/includes/database/sqlite/query.inc index 74ff9ba2..1bf609db 100644 --- a/includes/database/sqlite/query.inc +++ b/includes/database/sqlite/query.inc @@ -57,39 +57,18 @@ class InsertQuery_sqlite extends InsertQuery { * we don't select those rows. * * A query like this one: - * UPDATE test SET name = 'newname' WHERE tid = 1 + * UPDATE test SET col1 = 'newcol1', col2 = 'newcol2' WHERE tid = 1 * will become: - * UPDATE test SET name = 'newname' WHERE tid = 1 AND name <> 'newname' + * UPDATE test SET col1 = 'newcol1', col2 = 'newcol2' WHERE tid = 1 AND (col1 <> 'newcol1' OR col2 <> 'newcol2') */ class UpdateQuery_sqlite extends UpdateQuery { - /** - * Helper function that removes the fields that are already in a condition. - * - * @param $fields - * The fields. - * @param QueryConditionInterface $condition - * A database condition. - */ - protected function removeFieldsInCondition(&$fields, QueryConditionInterface $condition) { - foreach ($condition->conditions() as $child_condition) { - if ($child_condition['field'] instanceof QueryConditionInterface) { - $this->removeFieldsInCondition($fields, $child_condition['field']); - } - else { - unset($fields[$child_condition['field']]); - } - } - } - public function execute() { if (!empty($this->queryOptions['sqlite_return_matched_rows'])) { return parent::execute(); } - // Get the fields used in the update query, and remove those that are already - // in the condition. + // Get the fields used in the update query. $fields = $this->expressionFields + $this->fields; - $this->removeFieldsInCondition($fields, $this->condition); // Add the inverse of the fields to the condition. $condition = new DatabaseCondition('OR'); diff --git a/includes/entity.inc b/includes/entity.inc index 4f0c6c1d..2fefd590 100644 --- a/includes/entity.inc +++ b/includes/entity.inc @@ -160,18 +160,6 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface { public function load($ids = array(), $conditions = array()) { $entities = array(); - # PATCH http://drupal.org/node/1003788#comment-5195682 - // Clean the $ids array to remove non-integer values that can be passed - // in from various sources, including menu callbacks. - if (is_array($ids)) { - foreach ($ids as $key => $id) { - if (empty($id) || ((string) $id !== (string) (int) $id)) { - unset($ids[$key]); - } - } - } - # endpatch - // Revisions are not statically cached, and require a different query to // other conditions, so separate the revision id into its own variable. if ($this->revisionKey && isset($conditions[$this->revisionKey])) { diff --git a/includes/file.inc b/includes/file.inc index 278be3dd..e9a567e9 100644 --- a/includes/file.inc +++ b/includes/file.inc @@ -89,7 +89,7 @@ define('FILE_STATUS_PERMANENT', 1); * wrappers that are appropriate for particular usage. For example, this returns * only stream wrappers that use local file storage: * @code - * $local_stream_wrappers = file_get_stream_wrappers(STEAM_WRAPPERS_LOCAL); + * $local_stream_wrappers = file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL); * @endcode * * The $filter parameter can only filter to types containing a particular flag. @@ -99,7 +99,7 @@ define('FILE_STATUS_PERMANENT', 1); * array_diff_key() function can be used to help with this. For example, this * returns only stream wrappers that do not use local file storage: * @code - * $remote_stream_wrappers = array_diff_key(file_get_stream_wrappers(STREAM_WRAPPERS_ALL), file_get_stream_wrappers(STEAM_WRAPPERS_LOCAL)); + * $remote_stream_wrappers = array_diff_key(file_get_stream_wrappers(STREAM_WRAPPERS_ALL), file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL)); * @endcode * * @param $filter @@ -282,10 +282,6 @@ function file_stream_wrapper_uri_normalize($uri) { $uri = $scheme . '://' . $target; } } - else { - // The default scheme is file:// - $url = 'file://' . $uri; - } return $uri; } @@ -834,9 +830,8 @@ function file_valid_uri($uri) { * A string specifying the filepath or URI of the source file. * @param $destination * A URI containing the destination that $source should be copied to. The - * URI may be a bare filepath (without a scheme) and in that case the default - * scheme (file://) will be used. If this value is omitted, Drupal's default - * files scheme will be used, usually "public://". + * URI may be a bare filepath (without a scheme). If this value is omitted, + * Drupal's default files scheme will be used, usually "public://". * @param $replace * Replace behavior when the destination file already exists: * - FILE_EXISTS_REPLACE - Replace the existing file. @@ -892,7 +887,7 @@ 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' => $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, '%directory' => $destination)); return FALSE; } @@ -2481,20 +2476,10 @@ function file_directory_temp() { function file_get_content_headers($file) { $name = mime_header_encode($file->filename); $type = mime_header_encode($file->filemime); - // Serve images, text, and flash content for display rather than download. - $inline_types = variable_get('file_inline_types', array('^text/', '^image/', 'flash$')); - $disposition = 'attachment'; - foreach ($inline_types as $inline_type) { - // Exclamation marks are used as delimiters to avoid escaping slashes. - if (preg_match('!' . $inline_type . '!', $file->filemime)) { - $disposition = 'inline'; - } - } return array( 'Content-Type' => $type, 'Content-Length' => $file->filesize, - 'Content-Disposition' => $disposition . '; filename="' . $name . '"', 'Cache-Control' => 'private', ); } diff --git a/includes/filetransfer/filetransfer.inc b/includes/filetransfer/filetransfer.inc index 023b866e..6c55b2f4 100644 --- a/includes/filetransfer/filetransfer.inc +++ b/includes/filetransfer/filetransfer.inc @@ -406,10 +406,20 @@ class SkipDotsRecursiveDirectoryIterator extends RecursiveDirectoryIterator { */ function __construct($path) { parent::__construct($path); + $this->skipdots(); + } + + function rewind() { + parent::rewind(); + $this->skipdots(); } function next() { parent::next(); + $this->skipdots(); + } + + protected function skipdots() { while ($this->isDot()) { parent::next(); } diff --git a/includes/form.inc b/includes/form.inc index aa90eca6..8ae8065a 100644 --- a/includes/form.inc +++ b/includes/form.inc @@ -3058,7 +3058,6 @@ function form_process_radios($element) { */ function theme_checkbox($variables) { $element = $variables['element']; - $t = get_t(); $element['#attributes']['type'] = 'checkbox'; element_set_attributes($element, array('id', 'name', '#return_value' => 'value')); @@ -3662,35 +3661,6 @@ function form_pre_render_fieldset($element) { /** * Creates a group formatted as vertical tabs. * - * Note that autocomplete callbacks should include special handling as the - * user's input may contain forward slashes. If the user-submitted string has a - * '/' in the text that is sent in the autocomplete request, the menu system - * will split the text and pass it to the callback as multiple arguments. - * - * Suppose your autocomplete path in the menu system is 'mymodule_autocomplete.' - * In your form you have: - * @code - * '#autocomplete_path' => 'mymodule_autocomplete/' . $some_key . '/' . $some_id, - * @endcode - * The user types in "keywords" so the full path called is: - * 'mymodule_autocomplete/$some_key/$some_id/keywords' - * - * You should include code similar to the following to handle slashes in the - * input: - * @code - * function mymodule_autocomplete_callback($arg1, $arg2, $keywords) { - * $args = func_get_args(); - * // We need to remove $arg1 and $arg2 from the beginning of the array so we - * // are left with the keywords. - * array_shift($args); - * array_shift($args); - * // We store the user's original input in $keywords, including any slashes. - * $keywords = implode('/', $args); - * - * // Your code here. - * } - * @endcode - * * @param $element * An associative array containing the properties and children of the * fieldset. @@ -4039,8 +4009,6 @@ function theme_file($variables) { */ function theme_form_element($variables) { $element = &$variables['element']; - // This is also used in the installer, pre-database setup. - $t = get_t(); // This function is invoked as theme wrapper, but the rendered form element // may not necessarily have been processed by form_builder(). @@ -4199,7 +4167,7 @@ function _form_set_class(&$element, $class = array()) { if (!empty($element['#required'])) { $element['#attributes']['class'][] = 'required'; } - if (isset($element['#parents']) && form_get_error($element) !== NULL) { + if (isset($element['#parents']) && form_get_error($element) !== NULL && !empty($element['#validated'])) { $element['#attributes']['class'][] = 'error'; } } diff --git a/includes/image.inc b/includes/image.inc index ee5a086d..e30a3385 100644 --- a/includes/image.inc +++ b/includes/image.inc @@ -233,11 +233,11 @@ function image_dimensions_scale(array &$dimensions, $width = NULL, $height = NUL * @param $image * An image object returned by image_load(). * @param $width - * The target width, in pixels. This value is omitted then the scaling will - * based only on the height value. + * The target width, in pixels. If this value is NULL then the scaling will + * be based only on the height value. * @param $height - * The target height, in pixels. This value is omitted then the scaling will - * based only on the width value. + * The target height, in pixels. If this value is NULL then the scaling will + * be based only on the width value. * @param $upscale * Boolean indicating that files smaller than the dimensions will be scaled * up. This generally results in a low quality image. diff --git a/includes/install.core.inc b/includes/install.core.inc index 9805e1c8..7a694e9b 100644 --- a/includes/install.core.inc +++ b/includes/install.core.inc @@ -1041,7 +1041,21 @@ function install_select_profile(&$install_state) { } /** - * Selects an installation profile from a list or from a $_POST submission. + * Selects an installation profile. + * + * A profile will be selected if: + * - Only one profile is available, + * - A profile was submitted through $_POST, + * - Exactly one of the profiles is marked as "exclusive". + * If multiple profiles are marked as "exclusive" then no profile will be + * selected. + * + * @param array $profiles + * An associative array of profiles with the machine-readable names as keys. + * + * @return + * The machine-readable name of the selected profile or NULL if no profile was + * selected. */ function _install_select_profile($profiles) { if (sizeof($profiles) == 0) { @@ -1061,6 +1075,23 @@ function _install_select_profile($profiles) { } } } + // Check for a profile marked as "exclusive" and ensure that only one + // profile is marked as such. + $exclusive_profile = NULL; + foreach ($profiles as $profile) { + $profile_info = install_profile_info($profile->name); + if (!empty($profile_info['exclusive'])) { + if (empty($exclusive_profile)) { + $exclusive_profile = $profile->name; + } + else { + // We found a second "exclusive" profile. There's no way to choose + // between them, so we ignore the property. + return; + } + } + } + return $exclusive_profile; } /** diff --git a/includes/install.inc b/includes/install.inc index 0372483b..c4bcb88b 100644 --- a/includes/install.inc +++ b/includes/install.inc @@ -1244,6 +1244,12 @@ function drupal_check_module($module) { * - distribution_name: The name of the Drupal distribution that is being * installed, to be shown throughout the installation process. Defaults to * 'Drupal'. + * - exclusive: If the install profile is intended to be the only eligible + * choice in a distribution, setting exclusive = TRUE will auto-select it + * during installation, and the install profile selection screen will be + * skipped. If more than one profile is found where exclusive = TRUE then + * this property will have no effect and the profile selection screen will + * be shown as normal with all available profiles shown. * * Note that this function does an expensive file system scan to get info file * information for dependencies. If you only need information from the info diff --git a/includes/language.inc b/includes/language.inc index d0ea8311..ea63948d 100644 --- a/includes/language.inc +++ b/includes/language.inc @@ -2,7 +2,9 @@ /** * @file - * Multiple language handling functionality. + * Language Negotiation API. + * + * @see http://drupal.org/node/1497272 */ /** @@ -11,7 +13,96 @@ define('LANGUAGE_NEGOTIATION_DEFAULT', 'language-default'); /** - * Return all the defined language types. + * @defgroup language_negotiation Language Negotiation API functionality + * @{ + * Functions to customize the language types and the negotiation process. + * + * The language negotiation API is based on two major concepts: + * - Language types: types of translatable data (the types of data that a user + * can view or request). + * - Language negotiation providers: functions for determining which language to + * use to present a particular piece of data to the user. + * Both language types and language negotiation providers are customizable. + * + * Drupal defines three built-in language types: + * - Interface language: The page's main language, used to present translated + * user interface elements such as titles, labels, help text, and messages. + * - Content language: The language used to present content that is available + * in more than one language (see + * @link field_language Field Language API @endlink for details). + * - URL language: The language associated with URLs. When generating a URL, + * this value will be used by url() as a default if no explicit preference is + * provided. + * Modules can define additional language types through + * hook_language_types_info(), and alter existing language type definitions + * through hook_language_types_info_alter(). + * + * Language types may be configurable or fixed. The language negotiation + * providers associated with a configurable language type can be explicitly + * set through the user interface. A fixed language type has predetermined + * (module-defined) language negotiation settings and, thus, does not appear in + * the configuration page. Here is a code snippet that makes the content + * language (which by default inherits the interface language's values) + * configurable: + * @code + * function mymodule_language_types_info_alter(&$language_types) { + * unset($language_types[LANGUAGE_TYPE_CONTENT]['fixed']); + * } + * @endcode + * + * Every language type can have a different set of language negotiation + * providers assigned to it. Different language types often share the same + * language negotiation settings, but they can have independent settings if + * needed. If two language types are configured the same way, their language + * switcher configuration will be functionally identical and the same settings + * will act on both language types. + * + * Drupal defines the following built-in language negotiation providers: + * - URL: Determine the language from the URL (path prefix or domain). + * - Session: Determine the language from a request/session parameter. + * - User: Follow the user's language preference. + * - Browser: Determine the language from the browser's language settings. + * - Default language: Use the default site language. + * Language negotiation providers are simple callback functions that implement a + * particular logic to return a language code. For instance, the URL provider + * searches for a valid path prefix or domain name in the current request URL. + * If a language negotiation provider does not return a valid language code, the + * next provider associated to the language type (based on provider weight) is + * invoked. + * + * Modules can define additional language negotiation providers through + * hook_language_negotiation_info(), and alter existing providers through + * hook_language_negotiation_info_alter(). Here is an example snippet that lets + * path prefixes be ignored for administrative paths: + * @code + * function mymodule_language_negotiation_info_alter(&$negotiation_info) { + * // Replace the core function with our own function. + * module_load_include('language', 'inc', 'language.negotiation'); + * $negotiation_info[LANGUAGE_NEGOTIATION_URL]['callbacks']['negotiation'] = 'mymodule_from_url'; + * $negotiation_info[LANGUAGE_NEGOTIATION_URL]['file'] = drupal_get_path('module', 'mymodule') . '/mymodule.module'; + * } + * + * function mymodule_from_url($languages) { + * // Use the core URL language negotiation provider to get a valid language + * // code. + * module_load_include('language', 'inc', 'language.negotiation'); + * $langcode = language_from_url($languages); + * + * // If we are on an administrative path, override with the default language. + * if (isset($_GET['q']) && strtok($_GET['q'], '/') == 'admin') { + * return language_default()->langcode; + * } + * return $langcode; + * } + * ?> + * @endcode + * + * For more information, see + * @link http://drupal.org/node/1497272 Language Negotiation API @endlink + */ + +/** + * Returns all the defined language types. * * @return * An array of language type names. The name will be used as the global @@ -30,11 +121,11 @@ function language_types_info() { } /** - * Return only the configurable language types. + * Returns only the configurable language types. * * A language type maybe configurable or fixed. A fixed language type is a type - * whose negotiation values are unchangeable and defined while defining the - * language type itself. + * whose language negotiation providers are module-defined and not altered + * through the user interface. * * @param $stored * Optional. By default retrieves values from the 'language_types' variable to @@ -68,7 +159,7 @@ function language_types_configurable($stored = TRUE) { } /** - * Disable the given language types. + * Disables the given language types. * * @param $types * An array of language types. @@ -122,16 +213,17 @@ function language_types_set() { } /** - * Check if a language provider is enabled. + * Checks whether a language negotiation provider is enabled for a language type. * * This has two possible behaviors: * - If $provider_id is given return its ID if enabled, FALSE otherwise. - * - If no ID is passed the first enabled language provider is returned. + * - If no ID is passed the first enabled language negotiation provider is + * returned. * * @param $type - * The language negotiation type. + * The language negotiation provider type. * @param $provider_id - * The language provider ID. + * The language negotiation provider ID. * * @return * The provider ID if it is enabled, FALSE otherwise. @@ -155,14 +247,13 @@ function language_negotiation_get($type, $provider_id = NULL) { } /** - * Check if the given language provider is enabled for any configurable language - * type. + * Checks if the language negotiation provider is enabled for any language type. * * @param $provider_id - * The language provider ID. + * The language negotiation provider ID. * * @return - * TRUE if there is at least one language type for which the give language + * TRUE if there is at least one language type for which the given language * provider is enabled, FALSE otherwise. */ function language_negotiation_get_any($provider_id) { @@ -176,7 +267,7 @@ function language_negotiation_get_any($provider_id) { } /** - * Return the language switch links for the given language. + * Returns the language switch links for the given language. * * @param $type * The language negotiation type. @@ -223,7 +314,7 @@ function language_negotiation_get_switch_links($type, $path) { } /** - * Updates language configuration to remove any language provider that is no longer defined. + * Removes any unused language negotation providers from the configuration. */ function language_negotiation_purge() { // Ensure that we are getting the defined language negotiation information. An @@ -246,12 +337,12 @@ function language_negotiation_purge() { } /** - * Save a list of language providers. + * Saves a list of language negotiation providers. * * @param $type * The language negotiation type. * @param $language_providers - * An array of language provider weights keyed by id. + * An array of language negotiation provider weights keyed by provider ID. * @see language_provider_weight() */ function language_negotiation_set($type, $language_providers) { @@ -277,7 +368,7 @@ function language_negotiation_set($type, $language_providers) { // If the provider does not express any preference about types, make it // available for any configurable type. $types = array_flip(isset($provider['types']) ? $provider['types'] : $default_types); - // Check if the provider is defined and has the right type. + // Check whether the provider is defined and has the right type. if (isset($types[$type])) { $provider_data = array(); foreach ($provider_fields as $field) { @@ -294,10 +385,10 @@ function language_negotiation_set($type, $language_providers) { } /** - * Return all the defined language providers. + * Returns all the defined language negotiation providers. * * @return - * An array of language providers. + * An array of language negotiation providers. */ function language_negotiation_info() { $language_providers = &drupal_static(__FUNCTION__); @@ -306,7 +397,7 @@ function language_negotiation_info() { // Collect all the module-defined language negotiation providers. $language_providers = module_invoke_all('language_negotiation_info'); - // Add the default language provider. + // Add the default language negotiation provider. $language_providers[LANGUAGE_NEGOTIATION_DEFAULT] = array( 'callbacks' => array('language' => 'language_from_default'), 'weight' => 10, @@ -314,7 +405,7 @@ function language_negotiation_info() { 'description' => t('Use the default site language (@language_name).', array('@language_name' => language_default()->native)), ); - // Let other modules alter the list of language providers. + // Let other modules alter the list of language negotiation providers. drupal_alter('language_negotiation_info', $language_providers); } @@ -322,16 +413,17 @@ function language_negotiation_info() { } /** - * Helper function used to cache the language providers results. + * Helper function used to cache the language negotiation providers results. * * @param $provider_id - * The language provider ID. + * The language negotiation provider's identifier. * @param $provider - * The language provider to be invoked. If not passed it will be explicitly - * loaded through language_negotiation_info(). + * (optional) An associative array of information about the provider to be + * invoked (see hook_language_negotiation_info() for details). If not passed + * in, it will be loaded through language_negotiation_info(). * * @return - * The language provider's return value. + * A language object representing the language chosen by the provider. */ function language_provider_invoke($provider_id, $provider = NULL) { $results = &drupal_static(__FUNCTION__); @@ -352,25 +444,26 @@ function language_provider_invoke($provider_id, $provider = NULL) { require_once DRUPAL_ROOT . '/' . $provider['file']; } - // If the language provider has no cache preference or this is satisfied - // we can execute the callback. + // If the language negotiation provider has no cache preference or this is + // satisfied we can execute the callback. $cache = !isset($provider['cache']) || $user->uid || $provider['cache'] == variable_get('cache', 0); $callback = isset($provider['callbacks']['language']) ? $provider['callbacks']['language'] : FALSE; $langcode = $cache && function_exists($callback) ? $callback($languages) : FALSE; $results[$provider_id] = isset($languages[$langcode]) ? $languages[$langcode] : FALSE; } - // Since objects are resources we need to return a clone to prevent the - // provider cache to be unintentionally altered. The same providers might be - // used with different language types based on configuration. + // Since objects are resources, we need to return a clone to prevent the + // language negotiation provider cache from being unintentionally altered. The + // same providers might be used with different language types based on + // configuration. return !empty($results[$provider_id]) ? clone($results[$provider_id]) : $results[$provider_id]; } /** - * Return the passed language provider weight or a default value. + * Returns the passed language negotiation provider weight or a default value. * * @param $provider - * A language provider data structure. + * A language negotiation provider data structure. * * @return * A numeric weight. @@ -381,16 +474,16 @@ function language_provider_weight($provider) { } /** - * Choose a language for the given type based on language negotiation settings. + * Chooses a language based on language negotiation provider settings. * * @param $type - * The language type. + * The language type key to find the language for. * * @return * The negotiated language object. */ function language_initialize($type) { - // Execute the language providers in the order they were set up and return the + // Execute the language negotiation providers in the order they were set up and return the // first valid language found. $negotiation = variable_get("language_negotiation_$type", array()); @@ -409,7 +502,7 @@ function language_initialize($type) { } /** - * Default language provider. + * Returns the default language negotiation provider. * * @return * The default language code. @@ -421,8 +514,8 @@ function language_from_default() { /** * Splits the given path into prefix and actual path. * - * Parse the given path and return the language object identified by the - * prefix and the actual path. + * Parse the given path and return the language object identified by the prefix + * and the actual path. * * @param $path * The path to split. @@ -482,3 +575,7 @@ function language_fallback_get_candidates($type = LANGUAGE_TYPE_CONTENT) { return $fallback_candidates; } + +/** + * @} End of "language_negotiation" + */ diff --git a/includes/mail.inc b/includes/mail.inc index 8479d8e9..bbb55357 100644 --- a/includes/mail.inc +++ b/includes/mail.inc @@ -93,7 +93,9 @@ define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || strpos($_SERVER['SERVER * will be {$module}_{$key}. * @param $to * The e-mail address or addresses where the message will be sent to. The - * formatting of this string must comply with RFC 2822. Some examples are: + * formatting of this string will be validated with the + * @link http://php.net/manual/filter.filters.validate.php PHP e-mail validation filter. @endlink + * Some examples are: * - user@example.com * - user@example.com, anotheruser@example.com * - User @@ -212,9 +214,9 @@ function drupal_mail($module, $key, $to, $language, $params = array(), $from = N * 'mail_system', which is a keyed array. The default implementation * is the class whose name is the value of 'default-system' key. A more specific * match first to key and then to module will be used in preference to the - * default. To specificy a different class for all mail sent by one module, set + * default. To specify a different class for all mail sent by one module, set * the class name as the value for the key corresponding to the module name. To - * specificy a class for a particular message sent by one module, set the class + * specify a class for a particular message sent by one module, set the class * name as the value for the array key that is the message id, which is * "${module}_${key}". * @@ -307,19 +309,21 @@ interface MailSystemInterface { * - id: A unique identifier of the e-mail type. Examples: 'contact_user_copy', * 'user_password_reset'. * - to: The mail address or addresses where the message will be sent to. - * The formatting of this string must comply with RFC 2822. Some examples: + * The formatting of this string will be validated with the + * @link http://php.net/manual/filter.filters.validate.php PHP e-mail validation filter. @endlink + * Some examples are: * - user@example.com * - user@example.com, anotheruser@example.com * - User * - User , Another User - * - subject: Subject of the e-mail to be sent. This must not contain any - * newline characters, or the mail may not be sent properly. - * - body: Message to be sent. Accepts both CRLF and LF line-endings. - * E-mail bodies must be wrapped. You can use drupal_wrap_mail() for - * smart plain text wrapping. - * - headers: Associative array containing all additional mail headers not - * defined by one of the other parameters. PHP's mail() looks for Cc - * and Bcc headers and sends the mail to addresses in these headers too. + * - subject: Subject of the e-mail to be sent. This must not contain any + * newline characters, or the mail may not be sent properly. + * - body: Message to be sent. Accepts both CRLF and LF line-endings. + * E-mail bodies must be wrapped. You can use drupal_wrap_mail() for + * smart plain text wrapping. + * - headers: Associative array containing all additional mail headers not + * defined by one of the other parameters. PHP's mail() looks for Cc and + * Bcc headers and sends the mail to addresses in these headers too. * * @return * TRUE if the mail was successfully accepted for delivery, otherwise FALSE. diff --git a/includes/menu.inc b/includes/menu.inc index 0cb9d23b..2be09032 100644 --- a/includes/menu.inc +++ b/includes/menu.inc @@ -618,6 +618,7 @@ function _menu_load_objects(&$item, &$map) { * $item['access'] becomes TRUE if the item is accessible, FALSE otherwise. */ function _menu_check_access(&$item, $map) { + $item['access'] = FALSE; // Determine access callback, which will decide whether or not the current // user has access to this path. $callback = empty($item['access_callback']) ? 0 : trim($item['access_callback']); diff --git a/includes/module.inc b/includes/module.inc index d932f07b..341cd791 100644 --- a/includes/module.inc +++ b/includes/module.inc @@ -898,9 +898,10 @@ function drupal_required_modules() { * hook_TYPE_alter() implementations in modules. It ensures a consistent * interface for all altering operations. * - * A maximum of 2 alterable arguments is supported. In case more arguments need - * to be passed and alterable, modules provide additional variables assigned by - * reference in the last $context argument: + * A maximum of 2 alterable arguments is supported (a third is supported for + * legacy reasons, but should not be used in new code). In case more arguments + * need to be passed and alterable, modules provide additional variables + * assigned by reference in the last $context argument: * @code * $context = array( * 'alterable' => &$alterable, @@ -939,8 +940,14 @@ function drupal_required_modules() { * (optional) An additional variable that is passed by reference. If more * context needs to be provided to implementations, then this should be an * associative array as described above. + * @param $context3 + * (optional) An additional variable that is passed by reference. This + * parameter is deprecated and will not exist in Drupal 8; consequently, it + * should not be used for new Drupal 7 code either. It is here only for + * backwards compatibility with older code that passed additional arguments + * to drupal_alter(). */ -function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL) { +function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL, &$context3 = NULL) { // Use the advanced drupal_static() pattern, since this is called very often. static $drupal_static_fast; if (!isset($drupal_static_fast)) { @@ -1053,6 +1060,6 @@ function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL) { } foreach ($functions[$cid] as $function) { - $function($data, $context1, $context2); + $function($data, $context1, $context2, $context3); } } diff --git a/includes/password.inc b/includes/password.inc index d4f5f738..3d5a400d 100644 --- a/includes/password.inc +++ b/includes/password.inc @@ -43,7 +43,7 @@ function _password_itoa64() { } /** - * Encode bytes into printable base 64 using the *nix standard from crypt(). + * Encodes bytes into printable base 64 using the *nix standard from crypt(). * * @param $input * The string containing bytes to encode. diff --git a/includes/path.inc b/includes/path.inc index 411a7a71..234430ea 100644 --- a/includes/path.inc +++ b/includes/path.inc @@ -386,7 +386,7 @@ function drupal_path_alias_whitelist_rebuild($source = NULL) { } /** - * Fetch a specific URL alias from the database. + * Fetches a specific URL alias from the database. * * @param $conditions * A string representing the source, a number representing the pid, or an @@ -475,11 +475,11 @@ function path_delete($criteria) { } /** - * Determine whether a path is in the administrative section of the site. + * Determines whether a path is in the administrative section of the site. * - * By default, paths are considered to be non-administrative. If a path does not - * match any of the patterns in path_get_admin_paths(), or if it matches both - * administrative and non-administrative patterns, it is considered + * By default, paths are considered to be non-administrative. If a path does + * not match any of the patterns in path_get_admin_paths(), or if it matches + * both administrative and non-administrative patterns, it is considered * non-administrative. * * @param $path @@ -503,7 +503,7 @@ function path_is_admin($path) { } /** - * Get a list of administrative and non-administrative paths. + * Gets a list of administrative and non-administrative paths. * * @return array * An associative array containing the following keys: diff --git a/includes/session.inc b/includes/session.inc index b04c18eb..16727df6 100644 --- a/includes/session.inc +++ b/includes/session.inc @@ -274,7 +274,7 @@ function drupal_session_initialize() { } /** - * Forcefully starts a session, preserving already set session data. + * Starts a session forcefully, preserving already set session data. * * @ingroup php_wrappers */ diff --git a/includes/tablesort.inc b/includes/tablesort.inc index 121a1b90..e589526c 100644 --- a/includes/tablesort.inc +++ b/includes/tablesort.inc @@ -55,7 +55,7 @@ class TableSort extends SelectQueryExtender { } /** - * Initialize the table sort context. + * Initializes the table sort context. */ protected function init() { $ts = $this->order(); @@ -115,7 +115,7 @@ function tablesort_init($header) { } /** - * Format a column header. + * Formats a column header. * * If the cell in question is the column header for the current sort criterion, * it gets special formatting. All possible sort criteria become links. @@ -126,6 +126,7 @@ function tablesort_init($header) { * An array of column headers in the format described in theme_table(). * @param $ts * The current table sort context as returned from tablesort_init(). + * * @return * A properly formatted cell, ready for _theme_table_cell(). */ @@ -151,7 +152,7 @@ function tablesort_header($cell, $header, $ts) { } /** - * Format a table cell. + * Formats a table cell. * * Adds a class attribute to all cells in the currently active column. * @@ -163,6 +164,7 @@ function tablesort_header($cell, $header, $ts) { * The current table sort context as returned from tablesort_init(). * @param $i * The index of the cell's table column. + * * @return * A properly formatted cell, ready for _theme_table_cell(). */ @@ -179,7 +181,7 @@ function tablesort_cell($cell, $header, $ts, $i) { } /** - * Compose a URL query parameter array for table sorting links. + * Composes a URL query parameter array for table sorting links. * * @return * A URL query parameter array that consists of all components of the current @@ -190,10 +192,11 @@ function tablesort_get_query_parameters() { } /** - * Determine the current sort criterion. + * Determines the current sort criterion. * * @param $headers * An array of column headers in the format described in theme_table(). + * * @return * An associative array describing the criterion, containing the keys: * - "name": The localized title of the table column. @@ -226,10 +229,11 @@ function tablesort_get_order($headers) { } /** - * Determine the current sort direction. + * Determines the current sort direction. * * @param $headers * An array of column headers in the format described in theme_table(). + * * @return * The current sort direction ("asc" or "desc"). */ diff --git a/includes/theme.inc b/includes/theme.inc index 777922f0..5920624d 100644 --- a/includes/theme.inc +++ b/includes/theme.inc @@ -65,7 +65,7 @@ function _drupal_theme_access($theme) { } /** - * Initialize the theme system by loading the theme. + * Initializes the theme system by loading the theme. */ function drupal_theme_initialize() { global $theme, $user, $theme_key; @@ -113,8 +113,9 @@ function drupal_theme_initialize() { } /** - * Initialize the theme system given already loaded information. This - * function is useful to initialize a theme when no database is present. + * Initializes the theme system given already loaded information. + * + * This function is useful to initialize a theme when no database is present. * * @param $theme * An object with the following information: @@ -235,7 +236,7 @@ function _drupal_theme_initialize($theme, $base_theme = array(), $registry_callb } /** - * Get the theme registry. + * Gets the theme registry. * * @param $complete * Optional boolean to indicate whether to return the complete theme registry @@ -280,7 +281,7 @@ function theme_get_registry($complete = TRUE) { } /** - * Set the callback that will be used by theme_get_registry() to fetch the registry. + * Sets the callback that will be used by theme_get_registry(). * * @param $callback * The name of the callback function. @@ -296,7 +297,7 @@ function _theme_registry_callback($callback = NULL, array $arguments = array()) } /** - * Get the theme_registry cache; if it doesn't exist, build it. + * Gets the theme_registry cache; if it doesn't exist, builds it. * * @param $theme * The loaded $theme object as returned by list_themes(). @@ -336,16 +337,17 @@ function _theme_load_registry($theme, $base_theme = NULL, $theme_engine = NULL, } /** - * Write the theme_registry cache into the database. + * Writes the theme_registry cache into the database. */ function _theme_save_registry($theme, $registry) { cache_set("theme_registry:$theme->name", $registry); } /** - * Force the system to rebuild the theme registry; this should be called - * when modules are added to the system, or when a dynamic system needs - * to add more theme hooks. + * Forces the system to rebuild the theme registry. + * + * This function should be called when modules are added to the system, or when + * a dynamic system needs to add more theme hooks. */ function drupal_theme_rebuild() { drupal_static_reset('theme_get_registry'); @@ -635,7 +637,8 @@ function _theme_process_registry(&$cache, $name, $type, $theme, $path) { $cache = $result + $cache; } - // Let themes have variable processors even if they didn't register a template. + // Let themes have variable processors even if they didn't register a + // template. if ($type == 'theme' || $type == 'base_theme') { foreach ($cache as $hook => $info) { // Check only if not registered by the theme or engine. @@ -662,7 +665,7 @@ function _theme_process_registry(&$cache, $name, $type, $theme, $path) { } /** - * Build the theme registry cache. + * Builds the theme registry cache. * * @param $theme * The loaded $theme object as returned by list_themes(). @@ -724,7 +727,7 @@ function _theme_build_registry($theme, $base_theme, $theme_engine) { } /** - * Return a list of all currently available themes. + * Returns a list of all currently available themes. * * Retrieved from the database, if available and the site is not in maintenance * mode; otherwise compiled freshly from the filesystem. @@ -766,7 +769,7 @@ function _theme_build_registry($theme, $base_theme, $theme_engine) { * their base theme), direct sub-themes of sub-themes, etc. The keys are * the themes' machine names, and the values are the themes' human-readable * names. This element is not set if there are no themes on the system that - * declare this theme as their base theme. + * declare this theme as their base theme. */ function list_themes($refresh = FALSE) { $list = &drupal_static(__FUNCTION__, array()); @@ -900,15 +903,15 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) { * executed (if they exist), in the following order (note that in the following * list, HOOK indicates the theme hook name, MODULE indicates a module name, * THEME indicates a theme name, and ENGINE indicates a theme engine name): - * - template_preprocess(&$variables, $hook): Creates a default set of variables - * for all theme hooks with template implementations. + * - template_preprocess(&$variables, $hook): Creates a default set of + * variables for all theme hooks with template implementations. * - template_preprocess_HOOK(&$variables): Should be implemented by the module * that registers the theme hook, to set up default variables. * - MODULE_preprocess(&$variables, $hook): hook_preprocess() is invoked on all * implementing modules. * - MODULE_preprocess_HOOK(&$variables): hook_preprocess_HOOK() is invoked on - * all implementing modules, so that modules that didn't define the theme hook - * can alter the variables. + * all implementing modules, so that modules that didn't define the theme + * hook can alter the variables. * - ENGINE_engine_preprocess(&$variables, $hook): Allows the theme engine to * set necessary variables for all theme hooks with template implementations. * - ENGINE_engine_preprocess_HOOK(&$variables): Allows the theme engine to set @@ -963,10 +966,10 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) { * @param $hook * The name of the theme hook to call. If the name contains a * double-underscore ('__') and there isn't an implementation for the full - * name, the part before the '__' is checked. This allows a fallback to a more - * generic implementation. For example, if theme('links__node', ...) is - * called, but there is no implementation of that theme hook, then the 'links' - * implementation is used. This process is iterative, so if + * name, the part before the '__' is checked. This allows a fallback to a + * more generic implementation. For example, if theme('links__node', ...) is + * called, but there is no implementation of that theme hook, then the + * 'links' implementation is used. This process is iterative, so if * theme('links__contextual__node', ...) is called, theme() checks for the * following implementations, and uses the first one that exists: * - links__contextual__node @@ -1030,7 +1033,7 @@ function theme($hook, $variables = array()) { // Only log a message when not trying theme suggestions ($hook being an // array). if (!isset($candidate)) { - watchdog('theme', 'Theme key "@key" not found.', array('@key' => $hook), WATCHDOG_WARNING); + watchdog('theme', 'Theme hook %hook not found.', array('%hook' => $hook), WATCHDOG_WARNING); } return ''; } @@ -1042,7 +1045,8 @@ function theme($hook, $variables = array()) { // point path_to_theme() to the currently used theme path: $theme_path = $info['theme path']; - // Include a file if the theme function or variable processor is held elsewhere. + // Include a file if the theme function or variable processor is held + // elsewhere. if (!empty($info['includes'])) { foreach ($info['includes'] as $include_file) { include_once DRUPAL_ROOT . '/' . $include_file; @@ -1191,14 +1195,14 @@ function theme($hook, $variables = array()) { } /** - * Return the path to the current themed element. + * Returns the path to the current themed element. * - * It can point to the active theme or the module handling a themed implementation. - * For example, when invoked within the scope of a theming call it will depend - * on where the theming function is handled. If implemented from a module, it - * will point to the module. If implemented from the active theme, it will point - * to the active theme. When called outside the scope of a theming call, it will - * always point to the active theme. + * It can point to the active theme or the module handling a themed + * implementation. For example, when invoked within the scope of a theming call + * it will depend on where the theming function is handled. If implemented from + * a module, it will point to the module. If implemented from the active theme, + * it will point to the active theme. When called outside the scope of a + * theming call, it will always point to the active theme. */ function path_to_theme() { global $theme_path; @@ -1211,7 +1215,7 @@ function path_to_theme() { } /** - * Allow themes and/or theme engines to easily discover overridden theme functions. + * Allows themes and/or theme engines to discover overridden theme functions. * * @param $cache * The existing cache of theme hooks to test against. @@ -1268,7 +1272,7 @@ function drupal_find_theme_functions($cache, $prefixes) { } /** - * Allow themes and/or theme engines to easily discover overridden templates. + * Allows themes and/or theme engines to easily discover overridden templates. * * @param $cache * The existing cache of theme hooks to test against. @@ -1345,7 +1349,8 @@ function drupal_find_theme_templates($cache, $extension, $path) { if ($matches) { foreach ($matches as $match) { $file = substr($match, 0, strpos($match, '.')); - // Put the underscores back in for the hook name and register this pattern. + // Put the underscores back in for the hook name and register this + // pattern. $arg_name = isset($info['variables']) ? 'variables' : 'render element'; $implementations[strtr($file, '-', '_')] = array( 'template' => $file, @@ -1361,7 +1366,7 @@ function drupal_find_theme_templates($cache, $extension, $path) { } /** - * Retrieve a setting for the current theme or for a given theme. + * Retrieves a setting for the current theme or for a given theme. * * The final setting is obtained from the last value found in the following * sources: @@ -1479,7 +1484,7 @@ function theme_get_setting($setting_name, $theme = NULL) { } /** - * Render a system default template, which is essentially a PHP template. + * Renders a system default template, which is essentially a PHP template. * * @param $template_file * The filename of the template to render. @@ -1490,14 +1495,21 @@ function theme_get_setting($setting_name, $theme = NULL) { * The output generated by the template. */ function theme_render_template($template_file, $variables) { - extract($variables, EXTR_SKIP); // Extract the variables to a local namespace - ob_start(); // Start output buffering - include DRUPAL_ROOT . '/' . $template_file; // Include the template file - return ob_get_clean(); // End buffering and return its contents + // Extract the variables to a local namespace + extract($variables, EXTR_SKIP); + + // Start output buffering + ob_start(); + + // Include the template file + include DRUPAL_ROOT . '/' . $template_file; + + // End buffering and return its contents + return ob_get_clean(); } /** - * Enable a given list of themes. + * Enables a given list of themes. * * @param $theme_list * An array of theme names. @@ -1522,7 +1534,7 @@ function theme_enable($theme_list) { } /** - * Disable a given list of themes. + * Disables a given list of themes. * * @param $theme_list * An array of theme names. @@ -1608,13 +1620,13 @@ function theme_status_messages($variables) { * theme('link') for rendering the anchor tag. * * To optimize performance for sites that don't need custom theming of links, - * the l() function includes an inline copy of this function, and uses that copy - * if none of the enabled modules or the active theme implement any preprocess - * or process functions or override this theme implementation. + * the l() function includes an inline copy of this function, and uses that + * copy if none of the enabled modules or the active theme implement any + * preprocess or process functions or override this theme implementation. * * @param $variables - * An associative array containing the keys 'text', 'path', and 'options'. See - * the l() function for information about these variables. + * An associative array containing the keys 'text', 'path', and 'options'. + * See the l() function for information about these variables. * * @see l() */ @@ -1635,15 +1647,16 @@ function theme_link($variables) { * item in the links list. * - html: (optional) Whether or not 'title' is HTML. If set, the title * will not be passed through check_plain(). - * - attributes: (optional) Attributes for the anchor, or for the tag - * used in its place if no 'href' is supplied. If element 'class' is + * - attributes: (optional) Attributes for the anchor, or for the + * tag used in its place if no 'href' is supplied. If element 'class' is * included, it must be an array of one or more class names. - * If the 'href' element is supplied, the entire link array is passed to l() - * as its $options parameter. + * If the 'href' element is supplied, the entire link array is passed to + * l() as its $options parameter. * - attributes: A keyed array of attributes for the UL containing the * list of links. - * - heading: (optional) A heading to precede the links. May be an associative - * array or a string. If it's an array, it can have the following elements: + * - heading: (optional) A heading to precede the links. May be an + * associative array or a string. If it's an array, it can have the + * following elements: * - text: The heading text. * - level: The heading level (e.g. 'h2', 'h3'). * - class: (optional) An array of the CSS classes for the heading. @@ -1747,8 +1760,8 @@ function theme_links($variables) { * attribute to be omitted in some cases. Therefore, this variable defaults * to an empty string, but can be set to NULL for the attribute to be * omitted. Usually, neither omission nor an empty string satisfies - * accessibility requirements, so it is strongly encouraged for code calling - * theme('image') to pass a meaningful value for this variable. + * accessibility requirements, so it is strongly encouraged for code + * calling theme('image') to pass a meaningful value for this variable. * - http://www.w3.org/TR/REC-html40/struct/objects.html#h-13.8 * - http://www.w3.org/TR/xhtml1/dtds.html * - http://dev.w3.org/html5/spec/Overview.html#alt @@ -2005,7 +2018,8 @@ function theme_table($variables) { * * @param $variables * An associative array containing: - * - style: Set to either 'asc' or 'desc', this determines which icon to show. + * - style: Set to either 'asc' or 'desc', this determines which icon to + * show. */ function theme_tablesort_indicator($variables) { if ($variables['style'] == "asc") { @@ -2148,7 +2162,8 @@ function theme_feed_icon($variables) { * - script: To load JavaScript. * - #attributes: (optional) An array of HTML attributes to apply to the * tag. - * - #value: (optional) A string containing tag content, such as inline CSS. + * - #value: (optional) A string containing tag content, such as inline + * CSS. * - #value_prefix: (optional) A string to prepend to #value, e.g. a CDATA * wrapper prefix. * - #value_suffix: (optional) A string to append to #value, e.g. a CDATA @@ -2316,8 +2331,9 @@ function template_preprocess(&$variables, $hook) { global $user; static $count = array(); - // Track run count for each hook to provide zebra striping. - // See "template_preprocess_block()" which provides the same feature specific to blocks. + // Track run count for each hook to provide zebra striping. See + // "template_preprocess_block()" which provides the same feature specific to + // blocks. $count[$hook] = isset($count[$hook]) && is_int($count[$hook]) ? $count[$hook] : 1; $variables['zebra'] = ($count[$hook] % 2) ? 'odd' : 'even'; $variables['id'] = $count[$hook]++; @@ -2677,13 +2693,13 @@ function theme_get_suggestions($args, $base, $delimiter = '__') { } /** - * The variables array generated here is a mirror of template_preprocess_page(). - * This preprocessor will run its course when theme_maintenance_page() is - * invoked. + * Process variables for maintenance-page.tpl.php. * - * An alternate template file of "maintenance-page--offline.tpl.php" can be - * used when the database is offline to hide errors and completely replace the - * content. + * The variables array generated here is a mirror of + * template_preprocess_page(). This preprocessor will run its course when + * theme_maintenance_page() is invoked. An alternate template file of + * maintenance-page--offline.tpl.php can be used when the database is offline to + * hide errors and completely replace the content. * * The $variables array contains the following arguments: * - $content @@ -2777,10 +2793,13 @@ function template_preprocess_maintenance_page(&$variables) { } /** + * Theme process function for theme_maintenance_field(). + * * The variables array generated here is a mirror of template_process_html(). * This processor will run its course when theme_maintenance_page() is invoked. * * @see maintenance-page.tpl.php + * @see template_process_html() */ function template_process_maintenance_page(&$variables) { $variables['head'] = drupal_get_html_head(); @@ -2792,7 +2811,7 @@ function template_process_maintenance_page(&$variables) { /** * Preprocess variables for region.tpl.php * - * Prepare the values passed to the theme_region function to be passed into a + * Prepares the values passed to the theme_region function to be passed into a * pluggable template engine. Uses the region name to generate a template file * suggestions. If none are found, the default region.tpl.php is used. * diff --git a/includes/theme.maintenance.inc b/includes/theme.maintenance.inc index 218a8ada..6baf219b 100644 --- a/includes/theme.maintenance.inc +++ b/includes/theme.maintenance.inc @@ -10,9 +10,9 @@ * * Used for site installs, updates and when the site is in maintenance mode. * It also applies when the database is unavailable or bootstrap was not - * complete. Seven is always used for the initial install and update operations. - * In other cases, Bartik is used, but this can be overridden by setting a - * "maintenance_theme" key in the $conf variable in settings.php. + * complete. Seven is always used for the initial install and update + * operations. In other cases, Bartik is used, but this can be overridden by + * setting a "maintenance_theme" key in the $conf variable in settings.php. */ function _drupal_maintenance_theme() { global $theme, $theme_key, $conf; @@ -85,7 +85,7 @@ function _drupal_maintenance_theme() { } /** - * This builds the registry when the site needs to bypass any database calls. + * Builds the registry when the site needs to bypass any database calls. */ function _theme_load_offline_registry($theme, $base_theme = NULL, $theme_engine = NULL) { return _theme_build_registry($theme, $base_theme, $theme_engine); @@ -160,7 +160,7 @@ function theme_update_page($variables) { } /** - * Returns HTML for a report of the results from an operation run via authorize.php. + * Returns HTML for a results report of an operation run by authorize.php. * * @param $variables * An associative array containing: diff --git a/includes/token.inc b/includes/token.inc index 0b05c68f..5e9ece85 100644 --- a/includes/token.inc +++ b/includes/token.inc @@ -113,13 +113,13 @@ function token_replace($text, array $data = array(), array $options = array()) { */ function token_scan($text) { // Matches tokens with the following pattern: [$type:$name] - // $type and $name may not contain [ ] or whitespace characters. - // $type may not contain : characters, but $name may. + // $type and $name may not contain [ ] characters. + // $type may not contain : or whitespace characters, but $name may. preg_match_all('/ \[ # [ - pattern start ([^\s\[\]:]*) # match $type not containing whitespace : [ or ] : # : - separator - ([^\s\[\]]*) # match $name not containing whitespace [ or ] + ([^\[\]]*) # match $name not containing [ or ] \] # ] - pattern end /x', $text, $matches); @@ -190,10 +190,10 @@ function token_generate($type, array $tokens, array $data = array(), array $opti } /** - * Given a list of tokens, returns those that begin with a specific prefix. + * Returns a list of tokens that begin with a specific prefix. * - * Used to extract a group of 'chained' tokens (such as [node:author:name]) from - * the full list of tokens found in text. For example: + * Used to extract a group of 'chained' tokens (such as [node:author:name]) + * from the full list of tokens found in text. For example: * @code * $data = array( * 'author:name' => '[node:author:name]', @@ -230,8 +230,10 @@ function token_find_with_prefix(array $tokens, $prefix, $delimiter = ':') { /** * Returns metadata describing supported tokens. * - * The metadata array contains token type, name, and description data as well as - * an optional pointer indicating that the token chains to another set of tokens. + * The metadata array contains token type, name, and description data as well + * as an optional pointer indicating that the token chains to another set of + * tokens. + * * For example: * @code * $data['types']['node'] = array( diff --git a/includes/unicode.inc b/includes/unicode.inc index 81a0a4df..fd497cca 100644 --- a/includes/unicode.inc +++ b/includes/unicode.inc @@ -1,5 +1,10 @@ ). + * Double-escaped entities will only be decoded once ("&lt;" becomes "<" + * , not "<"). Be careful when using this function, as decode_entities can + * revert previous sanitization efforts (<script> will become