Browse Source

update to D 7.17

Signed-off-by: bachy <git@g-u-i.net>
bachy 11 years ago
parent
commit
5396b3e2b5
100 changed files with 1620 additions and 1081 deletions
  1. 70 7
      CHANGELOG.txt
  2. 2 2
      INSTALL.txt
  3. 108 108
      MAINTAINERS.txt
  4. 35 0
      README.txt
  5. 1 1
      includes/ajax.inc
  6. 1 1
      includes/authorize.inc
  7. 75 71
      includes/bootstrap.inc
  8. 124 53
      includes/common.inc
  9. 2 2
      includes/database/database.inc
  10. 6 4
      includes/database/log.inc
  11. 11 0
      includes/database/pgsql/database.inc
  12. 10 21
      includes/entity.inc
  13. 0 15
      includes/errors.inc
  14. 4 4
      includes/file.inc
  15. 1 1
      includes/filetransfer/filetransfer.inc
  16. 106 60
      includes/form.inc
  17. 9 10
      includes/image.inc
  18. 53 38
      includes/install.core.inc
  19. 38 25
      includes/install.inc
  20. 1 1
      includes/iso.inc
  21. 14 3
      includes/language.inc
  22. 15 13
      includes/mail.inc
  23. 87 72
      includes/menu.inc
  24. 25 18
      includes/module.inc
  25. 19 1
      includes/session.inc
  26. 3 3
      includes/stream_wrappers.inc
  27. 8 6
      includes/theme.inc
  28. 2 2
      includes/unicode.inc
  29. 10 23
      includes/update.inc
  30. 2 3
      misc/autocomplete.js
  31. 1 1
      misc/collapse.js
  32. 2 2
      misc/states.js
  33. 1 1
      modules/aggregator/aggregator.admin.inc
  34. 15 18
      modules/aggregator/aggregator.api.php
  35. 3 3
      modules/aggregator/aggregator.info
  36. 38 16
      modules/aggregator/aggregator.install
  37. 3 4
      modules/aggregator/aggregator.module
  38. 2 1
      modules/aggregator/aggregator.processor.inc
  39. 98 60
      modules/aggregator/aggregator.test
  40. 3 3
      modules/aggregator/tests/aggregator_test.info
  41. 8 0
      modules/aggregator/tests/aggregator_test_rss091.xml
  42. 1 0
      modules/block/block.api.php
  43. 3 3
      modules/block/block.info
  44. 65 65
      modules/block/block.test
  45. 3 3
      modules/block/tests/block_test.info
  46. 3 3
      modules/block/tests/themes/block_test_theme/block_test_theme.info
  47. 3 3
      modules/blog/blog.info
  48. 1 1
      modules/book/book.admin.inc
  49. 3 3
      modules/book/book.info
  50. 6 0
      modules/book/book.js
  51. 3 3
      modules/color/color.info
  52. 2 1
      modules/comment/comment-wrapper.tpl.php
  53. 3 3
      modules/comment/comment.info
  54. 13 2
      modules/comment/comment.module
  55. 187 185
      modules/comment/comment.test
  56. 2 0
      modules/comment/comment.tpl.php
  57. 3 3
      modules/contact/contact.info
  58. 3 3
      modules/contextual/contextual.info
  59. 3 3
      modules/dashboard/dashboard.info
  60. 3 3
      modules/dblog/dblog.info
  61. 1 1
      modules/dblog/dblog.module
  62. 1 1
      modules/dblog/dblog.test
  63. 12 8
      modules/field/field.api.php
  64. 33 2
      modules/field/field.form.inc
  65. 3 3
      modules/field/field.info
  66. 7 2
      modules/field/field.info.inc
  67. 6 4
      modules/field/field.install
  68. 1 1
      modules/field/field.module
  69. 3 3
      modules/field/modules/field_sql_storage/field_sql_storage.info
  70. 1 1
      modules/field/modules/field_sql_storage/field_sql_storage.install
  71. 3 3
      modules/field/modules/list/list.info
  72. 3 3
      modules/field/modules/list/tests/list_test.info
  73. 3 3
      modules/field/modules/number/number.info
  74. 3 3
      modules/field/modules/options/options.info
  75. 3 3
      modules/field/modules/text/text.info
  76. 4 1
      modules/field/tests/field.test
  77. 7 7
      modules/field/tests/field_test.entity.inc
  78. 3 3
      modules/field/tests/field_test.info
  79. 2 0
      modules/field/theme/field.tpl.php
  80. 3 3
      modules/field_ui/field_ui.info
  81. 0 6
      modules/file/file.api.php
  82. 3 3
      modules/file/file.info
  83. 8 1
      modules/file/file.js
  84. 3 3
      modules/file/tests/file_module_test.info
  85. 3 3
      modules/filter/filter.info
  86. 3 3
      modules/forum/forum.info
  87. 7 5
      modules/forum/forum.module
  88. 8 0
      modules/forum/forum.test
  89. 3 3
      modules/help/help.info
  90. 9 4
      modules/image/image.field.inc
  91. 3 3
      modules/image/image.info
  92. 3 3
      modules/image/image.module
  93. 99 7
      modules/image/image.test
  94. 3 3
      modules/image/tests/image_module_test.info
  95. 10 1
      modules/image/tests/image_module_test.module
  96. 3 3
      modules/locale/locale.info
  97. 14 1
      modules/locale/locale.install
  98. 1 1
      modules/locale/locale.module
  99. 6 6
      modules/locale/locale.test
  100. 3 3
      modules/locale/tests/locale_test.info

+ 70 - 7
CHANGELOG.txt

@@ -1,4 +1,67 @@
 
+Drupal 7.17, 2012-11-07
+-----------------------
+- Changed the default value of the '404_fast_html' variable to have a DOCTYPE
+  declaration.
+- Made it possible to use associative arrays for the 'items' variable in
+  theme_item_list().
+- Fixed a bug which prevented required form elements without a title from being
+  given an "error" class when the form fails validation.
+- Prevented duplicate HTML IDs from appearing when two forms are displayed on
+  the same page and one of them is submitted with invalid data (minor markup
+  change).
+- Fixed a bug which prevented Drupal 6 to Drupal 7 upgrades on sites which had
+  stale data in the Upload module's database tables.
+- Fixed a bug in the States API which prevented certain types of form elements
+  from being disabled when requested.
+- Allowed aggregator feed items with author names longer than 255 characters to
+  have a truncated version saved to the database (rather than causing a fatal
+  error).
+- Allowed aggregator feed items to have URLs longer than 255 characters
+  (schema change which results in several columns in the Aggregator module's
+  database tables changing from VARCHAR to TEXT fields).
+- Added hook_taxonomy_term_view() and standardized the process for rendering
+  taxonomy terms to invoke hook_entity_view() and otherwise make it consistent
+  with other entities (API change: http://drupal.org/node/1808870).
+- Added hook_entity_view_mode_alter() to allow modules to change entity view
+  modes on display (API addition: http://drupal.org/node/1833086).
+- Fixed a bug which made database queries running a "LIKE" query on blob fields
+  fail on PostgreSQL databases. This caused errors during the Drupal 6 to
+  Drupal 7 upgrade.
+- Changed the hook_menu() entry for Drupal's rss.xml page to prevent extra path
+  components from being accidentally passed to the page callback function (data
+  structure change).
+- Removed a non-standard "name" attribute from Drupal's default Content-Type
+  header for file downloads.
+- Fixed the theme settings form to properly clean up submitted values in
+  $form_state['values'] when the form is submitted (data structure change).
+- Fixed an inconsistency by removing the colon from the end of the label on
+  multi-valued form fields (minor string change).
+- Added support for 'weight' in hook_field_widget_info() to allow modules to
+  control the order in which widgets are displayed in the Field UI.
+- Updated various tables in the OpenID and Book modules to use the default
+  "empty table" text pattern (string change).
+- Added proxy server support to drupal_http_request().
+- Added "lang" attributes to language links, to better support screen readers.
+- Fixed double occurrence of a "ul" HTML tag on secondary local tasks in the
+  Seven theme (markup change).
+- Fixed bugs which caused taxonomy vocabulary and shortcut set titles to be
+  double-escaped. The fix replaces the taxonomy vocabulary overview page and
+  "Edit shortcuts" menu items' title callback entries in hook_menu() with new
+  functions that do not escape HTML characters (data structure change).
+- Modified the Update manager module to allow drupal.org to collect usage
+  statistics for individual modules and themes, rather than only for entire
+  projects.
+- Modified the node listing database query on Drupal's default front page to
+  add table aliases for better query altering (this is a data structure change
+  affecting code which implements hook_query_alter() on this query).
+- Improved the translatability of the "Field type(s) in use" message on the
+  modules page (admin-facing string change).
+- Fixed a regression which caused a "call to undefined function
+  drupal_find_base_themes()" fatal error under rare circumstances.
+- Numerous API documentation improvements.
+- Additional automated test coverage.
+
 Drupal 7.16, 2012-10-17
 -----------------------
 - Fixed security issues (Arbitrary PHP code execution and information
@@ -315,8 +378,8 @@ Drupal 7.0, 2011-01-05
       order can now be customized using the Views module.
     * Removed the 'related terms' feature from taxonomy module since this can
       now be achieved with Field API.
-    * Added additional features to the default install profile, and implemented
-      a "slimmed down" install profile designed for developers.
+    * Added additional features to the default installation profile, and
+      implemented a "slimmed down" profile designed for developers.
     * Added a built-in, automated cron run feature, which is triggered by site
       visitors.
     * Added an administrator role which is assigned all permissions for
@@ -543,7 +606,7 @@ Drupal 6.16, 2010-03-03
   see SA-CORE-2010-001.
 - Better support for updated jQuery versions.
 - Reduced resource usage of update.module.
-- Fixed several issues relating to support of install profiles and
+- Fixed several issues relating to support of installation profiles and
   distributions.
 - Added a locking framework to avoid data corruption on long operations.
 - Fixed a variety of other bugs.
@@ -661,7 +724,7 @@ Drupal 6.0, 2008-02-13
    * Expands the severity levels from 3 (Error, Warning, Notice) to the 8
      levels defined in RFC 3164.
    * The watchdog module is now called dblog, and is optional, but enabled by
-     default in the default install profile.
+     default in the default installation profile.
    * Extended the database log module so log messages can be filtered.
    * Added syslog module: useful for monitoring large Drupal installations.
 - Added optional e-mail notifications when users are approved, blocked, or
@@ -716,7 +779,7 @@ Drupal 6.0, 2008-02-13
     * Themed the installer with the Garland theme.
     * Added form to provide initial site information during installation.
     * Added ability to provide extra installation steps programmatically.
-    * Made it possible to import interface translations at install time.
+    * Made it possible to import interface translations during installation.
 - Added the HTML corrector filter:
     * Fixes faulty and chopped off HTML in postings.
     * Tags are now automatically closed at the end of the teaser.
@@ -895,7 +958,7 @@ Drupal 5.0, 2007-01-15
 - Added web-based installer which can:
     * Check installation and run-time requirements
     * Automatically generate the database configuration file
-    * Install pre-made 'install profiles' or distributions
+    * Install pre-made installation profiles or distributions
     * Import the database structure with automatic table prefixing
     * Be localized
 - Added new default Garland theme
@@ -955,7 +1018,7 @@ Drupal 5.0, 2007-01-15
 - Removed the archive module.
 - Upgrade system:
     * Created space for update branches.
-- Forms API:
+- Form API:
     * Made it possible to programmatically submit forms.
     * Improved api for multistep forms.
 - Theme system:

+ 2 - 2
INSTALL.txt

@@ -89,8 +89,8 @@ INSTALLATION
    - Download a translation file for the correct Drupal version and language
      from the translation server: http://localize.drupal.org/translate/downloads
 
-   - Place the file into your installation profile's translations
-     directory. For instance, if you are using the Standard install profile,
+   - Place the file into your installation profile's translations directory.
+     For instance, if you are using the Standard installation profile,
      move the .po file into the directory:
 
        profiles/standard/translations/

+ 108 - 108
MAINTAINERS.txt

@@ -9,9 +9,9 @@ Branch maintainers
 The Drupal Core branch maintainers oversee the development of Drupal as a whole.
 The branch maintainers for Drupal 7 are:
 
-- Dries Buytaert 'dries' <http://drupal.org/user/1>
-- Angela Byron 'webchick' <http://drupal.org/user/24967>
-- David Rothstein 'David_Rothstein' <http://drupal.org/user/124982>
+- Dries Buytaert 'dries' http://drupal.org/user/1
+- Angela Byron 'webchick' http://drupal.org/user/24967
+- David Rothstein 'David_Rothstein' http://drupal.org/user/124982
 
 
 Component maintainers
@@ -23,134 +23,136 @@ information on their responsibilities, and to find out how to become a component
 maintainer. Current component maintainers for Drupal 7:
 
 Ajax system
-- Alex Bronstein 'effulgentsia' <http://drupal.org/user/78040>
-- Earl Miles 'merlinofchaos' <http://drupal.org/user/26979>
+- Alex Bronstein 'effulgentsia' http://drupal.org/user/78040
+- Earl Miles 'merlinofchaos' http://drupal.org/user/26979
 
 Base system
-- Károly Négyesi 'chx' <http://drupal.org/user/9446>
-- Damien Tournoud 'DamZ' <http://drupal.org/user/22211>
-- Moshe Weitzman 'moshe weitzman' <http://drupal.org/user/23>
+- Károly Négyesi 'chx' http://drupal.org/user/9446
+- Damien Tournoud 'DamZ' http://drupal.org/user/22211
+- Moshe Weitzman 'moshe weitzman' http://drupal.org/user/23
 
 Batch system
-- Yves Chedemois 'yched' <http://drupal.org/user/39567>
+- Yves Chedemois 'yched' http://drupal.org/user/39567
 
 Cache system
-- Damien Tournoud 'DamZ' <http://drupal.org/user/22211>
-- Nathaniel Catchpole 'catch' <http://drupal.org/user/35733>
+- Damien Tournoud 'DamZ' http://drupal.org/user/22211
+- Nathaniel Catchpole 'catch' http://drupal.org/user/35733
 
 Cron system
-- Károly Négyesi 'chx' <http://drupal.org/user/9446>
-- Derek Wright 'dww' <http://drupal.org/user/46549>
+- Károly Négyesi 'chx' http://drupal.org/user/9446
+- Derek Wright 'dww' http://drupal.org/user/46549
 
 Database system
-- Larry Garfield 'Crell' <http://drupal.org/user/26398>
+- Larry Garfield 'Crell' http://drupal.org/user/26398
 
   - MySQL driver
-    - Larry Garfield 'Crell' <http://drupal.org/user/26398>
-    - David Strauss 'David Strauss' <http://drupal.org/user/93254>
+    - Larry Garfield 'Crell' http://drupal.org/user/26398
+    - David Strauss 'David Strauss' http://drupal.org/user/93254
 
   - PostgreSQL driver
-    - Damien Tournoud 'DamZ' <http://drupal.org/user/22211>
-    - Josh Waihi 'fiasco' <http://drupal.org/user/188162>
+    - Damien Tournoud 'DamZ' http://drupal.org/user/22211
+    - Josh Waihi 'fiasco' http://drupal.org/user/188162
 
   - Sqlite driver
-    - Damien Tournoud 'DamZ' <http://drupal.org/user/22211>
-    - Károly Négyesi 'chx' <http://drupal.org/user/9446>
+    - Damien Tournoud 'DamZ' http://drupal.org/user/22211
+    - Károly Négyesi 'chx' http://drupal.org/user/9446
 
 Database update system
-- Károly Négyesi 'chx' <http://drupal.org/user/9446>
-- Ashok Modi 'btmash' <http://drupal.org/user/60422>
+- Károly Négyesi 'chx' http://drupal.org/user/9446
+- Ashok Modi 'BTMash' http://drupal.org/user/60422
 
 Entity system
-- Wolfgang Ziegler 'fago' <http://drupal.org/user/16747>
-- Nathaniel Catchpole 'catch' <http://drupal.org/user/35733>
-- Franz Heinzmann 'Frando' <http://drupal.org/user/21850>
+- Wolfgang Ziegler 'fago' http://drupal.org/user/16747
+- Nathaniel Catchpole 'catch' http://drupal.org/user/35733
+- Franz Heinzmann 'Frando' http://drupal.org/user/21850
 
 File system
-- Andrew Morton 'drewish' <http://drupal.org/user/34869>
-- Aaron Winborn 'aaron' <http://drupal.org/user/33420>
+- Andrew Morton 'drewish' http://drupal.org/user/34869
+- Aaron Winborn 'aaron' http://drupal.org/user/33420
 
 Form system
-- Károly Négyesi 'chx' <http://drupal.org/user/9446>
-- Alex Bronstein 'effulgentsia' <http://drupal.org/user/78040>
-- Wolfgang Ziegler 'fago' <http://drupal.org/user/16747>
-- Daniel F. Kudwien 'sun' <http://drupal.org/user/54136>
-- Franz Heinzmann 'Frando' <http://drupal.org/user/21850>
+- Károly Négyesi 'chx' http://drupal.org/user/9446
+- Alex Bronstein 'effulgentsia' http://drupal.org/user/78040
+- Wolfgang Ziegler 'fago' http://drupal.org/user/16747
+- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
+- Franz Heinzmann 'Frando' http://drupal.org/user/21850
 
 Image system
-- Andrew Morton 'drewish' <http://drupal.org/user/34869>
-- Nathan Haug 'quicksketch' <http://drupal.org/user/35821>
+- Andrew Morton 'drewish' http://drupal.org/user/34869
+- Nathan Haug 'quicksketch' http://drupal.org/user/35821
 
 Install system
-- David Rothstein 'David_Rothstein' <http://drupal.org/user/124982>
+- David Rothstein 'David_Rothstein' http://drupal.org/user/124982
 
 JavaScript
-- Théodore Biadala 'nod_' <http://drupal.org/user/598310>
+- Théodore Biadala 'nod_' http://drupal.org/user/598310
+- Steve De Jonghe 'seutje' http://drupal.org/user/264148
+- Jesse Renée Beach 'jessebeach' http://drupal.org/user/748566
 
 Language system
-- Francesco Placella 'plach' <http://drupal.org/user/183211>
-- Daniel F. Kudwien 'sun' <http://drupal.org/user/54136>
+- Francesco Placella 'plach' http://drupal.org/user/183211
+- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
 
 Lock system
-- Damien Tournoud 'DamZ' <http://drupal.org/user/22211>
+- Damien Tournoud 'DamZ' http://drupal.org/user/22211
 
 Mail system
 - ?
 
 Markup
-- Jacine Luisi 'Jacine' <http://drupal.org/user/88931>
-- Daniel F. Kudwien 'sun' <http://drupal.org/user/54136>
+- Jacine Luisi 'Jacine' http://drupal.org/user/88931
+- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
 
 Menu system
-- Peter Wolanin 'pwolanin' <http://drupal.org/user/49851>
-- Károly Négyesi 'chx' <http://drupal.org/user/9446>
+- Peter Wolanin 'pwolanin' http://drupal.org/user/49851
+- Károly Négyesi 'chx' http://drupal.org/user/9446
 
 Path system
-- Dave Reid 'davereid' <http://drupal.org/user/53892>
-- Nathaniel Catchpole 'catch' <http://drupal.org/user/35733>
+- Dave Reid 'davereid' http://drupal.org/user/53892
+- Nathaniel Catchpole 'catch' http://drupal.org/user/35733
 
 Render system
-- Moshe Weitzman 'moshe weitzman' <http://drupal.org/user/23>
-- Alex Bronstein 'effulgentsia' <http://drupal.org/user/78040>
-- Franz Heinzmann 'Frando' <http://drupal.org/user/21850>
+- Moshe Weitzman 'moshe weitzman' http://drupal.org/user/23
+- Alex Bronstein 'effulgentsia' http://drupal.org/user/78040
+- Franz Heinzmann 'Frando' http://drupal.org/user/21850
 
 Theme system
-- Earl Miles 'merlinofchaos' <http://drupal.org/user/26979>
-- Alex Bronstein 'effulgentsia' <http://drupal.org/user/78040>
-- Joon Park 'dvessel' <http://drupal.org/user/56782>
-- John Albin Wilkins 'JohnAlbin' <http://drupal.org/user/32095>
+- Earl Miles 'merlinofchaos' http://drupal.org/user/26979
+- Alex Bronstein 'effulgentsia' http://drupal.org/user/78040
+- Joon Park 'dvessel' http://drupal.org/user/56782
+- John Albin Wilkins 'JohnAlbin' http://drupal.org/user/32095
 
 Token system
-- Dave Reid 'davereid' <http://drupal.org/user/53892>
+- Dave Reid 'davereid' http://drupal.org/user/53892
 
 XML-RPC system
-- Frederic G. Marand 'fgm' <http://drupal.org/user/27985>
+- Frederic G. Marand 'fgm' http://drupal.org/user/27985
 
 
 Topic coordinators
 ------------------
 
 Accessibility
-- Everett Zufelt 'Everett Zufelt' <http://drupal.org/user/406552>
-- Brandon Bowersox-Johnson 'bowersox' <http://drupal.org/user/186415>
+- Everett Zufelt 'Everett Zufelt' http://drupal.org/user/406552
+- Brandon Bowersox-Johnson 'bowersox' http://drupal.org/user/186415
 
 Documentation
-- Jennifer Hodgdon 'jhodgdon' <http://drupal.org/user/155601>
+- Jennifer Hodgdon 'jhodgdon' http://drupal.org/user/155601
 
 Security
-- Heine Deelstra 'Heine' <http://drupal.org/user/17943>
+- Greg Knaddison 'greggles' http://drupal.org/user/36762
 
 Translations
-- Gerhard Killesreiter 'killes' <http://drupal.org/user/83>
+- Gerhard Killesreiter 'killes' http://drupal.org/user/83
 
 User experience and usability
-- Roy Scholten 'yoroy' <http://drupal.org/user/41502>
-- Bojhan Somers 'Bojhan' <http://drupal.org/user/87969>
+- Roy Scholten 'yoroy' http://drupal.org/user/41502
+- Bojhan Somers 'Bojhan' http://drupal.org/user/87969
 
 Node Access
-- Moshe Weitzman 'moshe weitzman' <http://drupal.org/user/23>
-- Ken Rickard 'agentrickard' <http://drupal.org/user/20975>
-- Jess Myrbo 'xjm' <http://drupal.org/user/65776>
+- Moshe Weitzman 'moshe weitzman' http://drupal.org/user/23
+- Ken Rickard 'agentrickard' http://drupal.org/user/20975
+- Jess Myrbo 'xjm' http://drupal.org/user/65776
 
 Module maintainers
 ------------------
@@ -159,145 +161,143 @@ Aggregator module
 - ?
 
 Block module
-- John Albin Wilkins 'JohnAlbin' <http://drupal.org/user/32095>
+- John Albin Wilkins 'JohnAlbin' http://drupal.org/user/32095
 
 Blog module
 - ?
 
 Book module
-- Peter Wolanin 'pwolanin' <http://drupal.org/user/49851>
+- Peter Wolanin 'pwolanin' http://drupal.org/user/49851
 
 Color module
 - ?
 
 Comment module
-- Nathaniel Catchpole 'catch' <http://drupal.org/user/35733>
+- Nathaniel Catchpole 'catch' http://drupal.org/user/35733
 
 Contact module
-- Dave Reid 'davereid' <http://drupal.org/user/53892>
+- Dave Reid 'davereid' http://drupal.org/user/53892
 
 Contextual module
-- Daniel F. Kudwien 'sun' <http://drupal.org/user/54136>
+- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
 
 Dashboard module
 - ?
 
 Database logging module
-- Khalid Baheyeldin 'kbahey' <http://drupal.org/user/4063>
+- Khalid Baheyeldin 'kbahey' http://drupal.org/user/4063
 
 Field module
-- Yves Chedemois 'yched' <http://drupal.org/user/39567>
-- Barry Jaspan 'bjaspan' <http://drupal.org/user/46413>
+- Yves Chedemois 'yched' http://drupal.org/user/39567
+- Barry Jaspan 'bjaspan' http://drupal.org/user/46413
 
 Field UI module
-- Yves Chedemois 'yched' <http://drupal.org/user/39567>
+- Yves Chedemois 'yched' http://drupal.org/user/39567
 
 File module
-- Aaron Winborn 'aaron' <http://drupal.org/user/33420>
+- Aaron Winborn 'aaron' http://drupal.org/user/33420
 
 Filter module
-- Daniel F. Kudwien 'sun' <http://drupal.org/user/54136>
+- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
 
 Forum module
-- Lee Rowlands 'larowlan' <http://drupal.org/user/395439>
+- Lee Rowlands 'larowlan' http://drupal.org/user/395439
 
 Help module
 - ?
 
 Image module
-- Nathan Haug 'quicksketch' <http://drupal.org/user/35821>
+- Nathan Haug 'quicksketch' http://drupal.org/user/35821
 
 Locale module
-- Gábor Hojtsy 'Gábor Hojtsy' <http://drupal.org/user/4166>
+- Gábor Hojtsy 'Gábor Hojtsy' http://drupal.org/user/4166
 
 Menu module
 - ?
 
 Node module
-- Moshe Weitzman 'moshe weitzman' <http://drupal.org/user/23>
-- David Strauss 'David Strauss' <http://drupal.org/user/93254>
+- Moshe Weitzman 'moshe weitzman' http://drupal.org/user/23
+- David Strauss 'David Strauss' http://drupal.org/user/93254
 
 OpenID module
-- Vojtech Kusy 'wojtha' <http://drupal.org/user/56154>
-- Heine Deelstra 'Heine' <http://drupal.org/user/17943>
-- Christian Schmidt 'c960657' <http://drupal.org/user/216078>
-- Damien Tournoud 'DamZ' <http://drupal.org/user/22211>
+- Vojtech Kusy 'wojtha' http://drupal.org/user/56154
+- Christian Schmidt 'c960657' http://drupal.org/user/216078
+- Damien Tournoud 'DamZ' http://drupal.org/user/22211
 
 Overlay module
-- Katherine Senzee 'ksenzee' <http://drupal.org/user/139855>
+- Katherine Senzee 'ksenzee' http://drupal.org/user/139855
 
 Path module
-- Dave Reid 'davereid' <http://drupal.org/user/53892>
+- Dave Reid 'davereid' http://drupal.org/user/53892
 
 PHP module
 - ?
 
 Poll module
-- Andrei Mateescu 'amateescu' <http://drupal.org/user/729614>
+- Andrei Mateescu 'amateescu' http://drupal.org/user/729614
 
 Profile module
 - ?
 
 RDF module
-- Stéphane Corlosquet 'scor' <http://drupal.org/user/52142>
+- Stéphane Corlosquet 'scor' http://drupal.org/user/52142
 
 Search module
-- Doug Green 'douggreen' <http://drupal.org/user/29191>
+- Doug Green 'douggreen' http://drupal.org/user/29191
 
 Shortcut module
-- David Rothstein 'David_Rothstein' <http://drupal.org/user/124982>
-- Kristof De Jaeger 'swentel' <http://drupal.org/user/107403>
+- David Rothstein 'David_Rothstein' http://drupal.org/user/124982
 
 Simpletest module
-- Jimmy Berry 'boombatower' <http://drupal.org/user/214218>
-- Károly Négyesi 'chx' <http://drupal.org/user/9446>
+- Jimmy Berry 'boombatower' http://drupal.org/user/214218
+- Károly Négyesi 'chx' http://drupal.org/user/9446
 
 Statistics module
-- Tim Millwood 'timmillwood' <http://drupal.org/user/227849>
+- Tim Millwood 'timmillwood' http://drupal.org/user/227849
 
 Syslog module
-- Khalid Baheyeldin 'kbahey' <http://drupal.org/user/4063>
+- Khalid Baheyeldin 'kbahey' http://drupal.org/user/4063
 
 System module
 - ?
 
 Taxonomy module
-- Jess Myrbo 'xjm' <http://drupal.org/user/65776>
-- Nathaniel Catchpole 'catch' <http://drupal.org/user/35733>
-- Benjamin Doherty 'bangpound' <http://drupal.org/user/100456>
+- Jess Myrbo 'xjm' http://drupal.org/user/65776
+- Nathaniel Catchpole 'catch' http://drupal.org/user/35733
+- Benjamin Doherty 'bangpound' http://drupal.org/user/100456
 
 Toolbar module
 - ?
 
 Tracker module
-- David Strauss 'David Strauss' <http://drupal.org/user/93254>
+- David Strauss 'David Strauss' http://drupal.org/user/93254
 
 Translation module
-- Francesco Placella 'plach' <http://drupal.org/user/183211>
+- Francesco Placella 'plach' http://drupal.org/user/183211
 
 Trigger module
 - ?
 
 Update module
-- Derek Wright 'dww' <http://drupal.org/user/46549>
+- Derek Wright 'dww' http://drupal.org/user/46549
 
 User module
-- Moshe Weitzman 'moshe weitzman' <http://drupal.org/user/23>
-- David Strauss 'David Strauss' <http://drupal.org/user/93254>
+- Moshe Weitzman 'moshe weitzman' http://drupal.org/user/23
+- David Strauss 'David Strauss' http://drupal.org/user/93254
 
 
 Theme maintainers
 -----------------
 
 Bartik theme
-- Jen Simmons 'jensimmons' <http://drupal.org/user/140882>
-- Jeff Burns 'Jeff Burnz' <http://drupal.org/user/61393>
+- Jen Simmons 'jensimmons' http://drupal.org/user/140882
+- Jeff Burns 'Jeff Burnz' http://drupal.org/user/61393
 
 Garland theme
-- John Albin Wilkins 'JohnAlbin' <http://drupal.org/user/32095>
+- John Albin Wilkins 'JohnAlbin' http://drupal.org/user/32095
 
 Seven theme
-- Jeff Burns 'Jeff Burnz' <http://drupal.org/user/61393>
+- Jeff Burns 'Jeff Burnz' http://drupal.org/user/61393
 
 Stark theme
-- John Albin Wilkins 'JohnAlbin' <http://drupal.org/user/32095>
+- John Albin Wilkins 'JohnAlbin' http://drupal.org/user/32095

+ 35 - 0
README.txt

@@ -4,6 +4,7 @@ CONTENTS OF THIS FILE
 
  * About Drupal
  * Configuration and features
+ * Installation profiles
  * Appearance
  * Developing for Drupal
 
@@ -43,6 +44,40 @@ More about configuration:
    http://drupal.org/project/modules
  * See also: "Developing for Drupal" for writing your own modules, below.
 
+INSTALLATION PROFILES
+---------------------
+
+Installation profiles define additional steps (such as enabling modules,
+defining content types, etc.) that run after the base installation provided
+by core when Drupal is first installed. There are two basic installation
+profiles provided with Drupal core.
+
+Installation profiles from the Drupal community modify the installation process
+to provide a website for a specific use case, such as a CMS for media
+publishers, a web-based project tracking tool, or a full-fledged CRM for
+non-profit organizations raising money and accepting donations. They can be
+distributed as bare installation profiles or as "distributions". Distributions
+include Drupal core, the installation profile, and all other required
+extensions, such as contributed and custom modules, themes, and third-party
+libraries. Bare installation profiles require you to download Drupal Core and
+the required extensions separately; place the downloaded profile in the
+/profiles directory before you start the installation process. Note that the
+contents of this directory may be overwritten during updates of Drupal core;
+it is advised to keep code backups or use a version control system.
+
+Additionally, modules and themes may be placed inside subdirectories in a
+specific installation profile such as profiles/your_site_profile/modules and
+profiles/your_site_profile/themes respectively to restrict their usage to only
+sites that were installed with that specific profile.
+
+More about installation profiles and distributions:
+* Read about the difference between installation profiles and distributions:
+  http://drupal.org/node/1089736
+* Download contributed installation profiles and distributions:
+  http://drupal.org/project/distributions
+* Develop your own installation profile or distribution:
+  http://drupal.org/developing/distributions
+
 APPEARANCE
 ----------
 

+ 1 - 1
includes/ajax.inc

@@ -168,7 +168,7 @@
  *   displayed while awaiting a response from the callback, and add an optional
  *   message. Possible keys: 'type', 'message', 'url', 'interval'.
  *   More information is available in the
- *   @link http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html/7 Form API Reference @endlink
+ *   @link forms_api_reference.html Form API Reference @endlink
  *
  * In addition to using Form API for doing in-form modification, Ajax may be
  * enabled by adding classes to buttons and links. By adding the 'use-ajax'

+ 1 - 1
includes/authorize.inc

@@ -18,7 +18,7 @@ function authorize_filetransfer_form($form, &$form_state) {
   global $base_url, $is_https;
   $form = array();
 
-  // If possible, we want to post this form securely via https.
+  // If possible, we want to post this form securely via HTTPS.
   $form['#https'] = TRUE;
 
   // CSS we depend on lives in modules/system/maintenance.css, which is loaded

+ 75 - 71
includes/bootstrap.inc

@@ -8,7 +8,7 @@
 /**
  * The current system version.
  */
-define('VERSION', '7.16');
+define('VERSION', '7.17');
 
 /**
  * Core API compatibility.
@@ -25,6 +25,21 @@ define('DRUPAL_MINIMUM_PHP', '5.2.4');
  */
 define('DRUPAL_MINIMUM_PHP_MEMORY_LIMIT', '32M');
 
+/**
+ * Error reporting level: display no errors.
+ */
+define('ERROR_REPORTING_HIDE', 0);
+
+/**
+ * Error reporting level: display errors and warnings.
+ */
+define('ERROR_REPORTING_DISPLAY_SOME', 1);
+
+/**
+ * Error reporting level: display all messages.
+ */
+define('ERROR_REPORTING_DISPLAY_ALL', 2);
+
 /**
  * Indicates that the item should never be removed unless explicitly selected.
  *
@@ -498,56 +513,12 @@ function timer_stop($name) {
 }
 
 /**
- * Finds the appropriate configuration directory.
+ * Returns the appropriate configuration directory.
  *
- * Finds a matching configuration directory by stripping the website's
- * hostname from left to right and pathname from right to left. The first
- * configuration file found will be used and the remaining ones will be ignored.
- * If no configuration file is found, return a default value '$confdir/default'.
- *
- * With a site located at http://www.example.com:8080/mysite/test/, the file,
- * settings.php, is searched for in the following directories:
- *
- * - $confdir/8080.www.example.com.mysite.test
- * - $confdir/www.example.com.mysite.test
- * - $confdir/example.com.mysite.test
- * - $confdir/com.mysite.test
- *
- * - $confdir/8080.www.example.com.mysite
- * - $confdir/www.example.com.mysite
- * - $confdir/example.com.mysite
- * - $confdir/com.mysite
- *
- * - $confdir/8080.www.example.com
- * - $confdir/www.example.com
- * - $confdir/example.com
- * - $confdir/com
- *
- * - $confdir/default
- *
- * If a file named sites.php is present in the $confdir, it will be loaded
- * prior to scanning for directories. It should define an associative array
- * named $sites, which maps domains to directories. It should be in the form
- * of:
- * @code
- * $sites = array(
- *   'The url to alias' => 'A directory within the sites directory'
- * );
- * @endcode
- * For example:
- * @code
- * $sites = array(
- *   'devexample.com' => 'example.com',
- *   'localhost.example' => 'example.com',
- * );
- * @endcode
- * The above array will cause Drupal to look for a directory named
- * "example.com" in the sites directory whenever a request comes from
- * "example.com", "devexample.com", or "localhost/example". That is useful
- * on development servers, where the domain name may not be the same as the
- * domain of the live server. Since Drupal stores file paths into the database
- * (files, system table, etc.) this will ensure the paths are correct while
- * accessed on development servers.
+ * Returns the configuration path based on the site's hostname, port, and
+ * pathname. Uses find_conf_path() to find the current configuration directory.
+ * See default.settings.php for examples on how the URL is converted to a
+ * directory.
  *
  * @param bool $require_settings
  *   Only configuration directories with an existing settings.php file
@@ -560,6 +531,8 @@ function timer_stop($name) {
  *
  * @return
  *   The path of the matching directory.
+ *
+ * @see default.settings.php
  */
 function conf_path($require_settings = TRUE, $reset = FALSE) {
   $conf = &drupal_static(__FUNCTION__, '');
@@ -731,7 +704,7 @@ function drupal_valid_http_host($host) {
 function drupal_settings_initialize() {
   global $base_url, $base_path, $base_root;
 
-  // Export the following settings.php variables to the global namespace
+  // Export these settings.php variables to the global namespace.
   global $databases, $cookie_domain, $conf, $installed_profile, $update_free_access, $db_url, $db_prefix, $drupal_hash_salt, $is_https, $base_secure_url, $base_insecure_url;
   $conf = array();
 
@@ -752,7 +725,7 @@ function drupal_settings_initialize() {
     $base_root = substr($base_url, 0, strlen($base_url) - strlen($parts['path']));
   }
   else {
-    // Create base URL
+    // Create base URL.
     $http_protocol = $is_https ? 'https' : 'http';
     $base_root = $http_protocol . '://' . $_SERVER['HTTP_HOST'];
 
@@ -778,7 +751,7 @@ function drupal_settings_initialize() {
   }
   else {
     // Otherwise use $base_url as session name, without the protocol
-    // to use the same session identifiers across http and https.
+    // to use the same session identifiers across HTTP and HTTPS.
     list( , $session_name) = explode('://', $base_url, 2);
     // HTTP_HOST can be modified by a visitor, but we already sanitized it
     // in drupal_settings_initialize().
@@ -1732,7 +1705,8 @@ function watchdog($type, $message, $variables = array(), $severity = WATCHDOG_NO
       'request_uri' => $base_root . request_uri(),
       'referer'     => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '',
       'ip'          => ip_address(),
-      'timestamp'   => REQUEST_TIME,
+      // Request time isn't accurate for long processes, use time() instead.
+      'timestamp'   => time(),
     );
 
     // Call the logging hooks to log/process the message
@@ -1798,18 +1772,29 @@ function drupal_set_message($message = NULL, $type = 'status', $repeat = TRUE) {
 }
 
 /**
- * Returns all messages that have been set.
+ * Returns all messages that have been set with drupal_set_message().
  *
- * @param $type
- *   (optional) Only return messages of this type.
- * @param $clear_queue
- *   (optional) Set to FALSE if you do not want to clear the messages queue
+ * @param string $type
+ *   (optional) Limit the messages returned by type. Defaults to NULL, meaning
+ *   all types. These values are supported:
+ *   - NULL
+ *   - 'status'
+ *   - 'warning'
+ *   - 'error'
+ * @param bool $clear_queue
+ *   (optional) If this is TRUE, the queue will be cleared of messages of the
+ *   type specified in the $type parameter. Otherwise the queue will be left
+ *   intact. Defaults to TRUE.
  *
- * @return
- *   An associative array, the key is the message type, the value an array
- *   of messages. If the $type parameter is passed, you get only that type,
- *   or an empty array if there are no such messages. If $type is not passed,
- *   all message types are returned, or an empty array if none exist.
+ * @return array
+ *   A multidimensional array with keys corresponding to the set message types.
+ *   The indexed array values of each contain the set messages for that type.
+ *   The messages returned are limited to the type specified in the $type
+ *   parameter. If there are no messages of the specified type, an empty array
+ *   is returned.
+ *
+ * @see drupal_set_message()
+ * @see theme_status_messages()
  */
 function drupal_get_messages($type = NULL, $clear_queue = TRUE) {
   if ($messages = drupal_set_message()) {
@@ -2115,14 +2100,26 @@ function drupal_anonymous_user() {
 /**
  * Ensures Drupal is bootstrapped to the specified phase.
  *
- * The bootstrap phase is an integer constant identifying a phase of Drupal
- * to load. Each phase adds to the previous one, so invoking a later phase
- * automatically runs the earlier phases as well. To access the Drupal
- * database from a script without loading anything else, include bootstrap.inc
- * and call drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE).
+ * In order to bootstrap Drupal from another PHP script, you can use this code:
+ * @code
+ *   define('DRUPAL_ROOT', '/path/to/drupal');
+ *   require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
+ *   drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
+ * @endcode
  *
  * @param $phase
- *   A constant. Allowed values are the DRUPAL_BOOTSTRAP_* constants.
+ *   A constant telling which phase to bootstrap to. When you bootstrap to a
+ *   particular phase, all earlier phases are run automatically. Possible
+ *   values:
+ *   - DRUPAL_BOOTSTRAP_CONFIGURATION: Initializes configuration.
+ *   - DRUPAL_BOOTSTRAP_PAGE_CACHE: Tries to serve a cached page.
+ *   - DRUPAL_BOOTSTRAP_DATABASE: Initializes the database layer.
+ *   - DRUPAL_BOOTSTRAP_VARIABLES: Initializes the variable system.
+ *   - DRUPAL_BOOTSTRAP_SESSION: Initializes session handling.
+ *   - DRUPAL_BOOTSTRAP_PAGE_HEADER: Sets up the page header.
+ *   - DRUPAL_BOOTSTRAP_LANGUAGE: Finds out the language of the page.
+ *   - DRUPAL_BOOTSTRAP_FULL: Fully loads Drupal. Validates and fixes input
+ *     data.
  * @param $new_phase
  *   A boolean, set to FALSE if calling drupal_bootstrap from inside a
  *   function called from drupal_bootstrap (recursion).
@@ -2521,7 +2518,7 @@ function drupal_fast_404() {
     $fast_paths = variable_get('404_fast_paths', FALSE);
     if ($fast_paths && preg_match($fast_paths, $_GET['q'])) {
       drupal_add_http_header('Status', '404 Not Found');
-      $fast_404_html = variable_get('404_fast_html', '<html xmlns="http://www.w3.org/1999/xhtml"><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "@path" was not found on this server.</p></body></html>');
+      $fast_404_html = variable_get('404_fast_html', '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "@path" was not found on this server.</p></body></html>');
       // Replace @path in the variable with the page path.
       print strtr($fast_404_html, array('@path' => check_plain(request_uri())));
       exit;
@@ -2614,6 +2611,9 @@ function drupal_language_types() {
 
 /**
  * Returns TRUE if there is more than one language enabled.
+ *
+ * @return
+ *   TRUE if more than one language is enabled.
  */
 function drupal_multilingual() {
   // The "language_count" variable stores the number of enabled languages to
@@ -2624,6 +2624,10 @@ function drupal_multilingual() {
 
 /**
  * Returns an array of the available language types.
+ *
+ * @return
+ *   An array of all language types where the keys of each are the language type
+ *   name and its value is its configurability (TRUE/FALSE).
  */
 function language_types() {
   return array_keys(variable_get('language_types', drupal_language_types()));

+ 124 - 53
includes/common.inc

@@ -92,14 +92,20 @@ define('JS_THEME', 100);
 define('HTTP_REQUEST_TIMEOUT', -1);
 
 /**
- * Constants defining cache granularity for blocks and renderable arrays.
- *
- * Modules specify the caching patterns for their blocks using binary
- * combinations of these constants in their hook_block_info():
- *   $block[delta]['cache'] = DRUPAL_CACHE_PER_ROLE | DRUPAL_CACHE_PER_PAGE;
- * DRUPAL_CACHE_PER_ROLE is used as a default when no caching pattern is
- * specified. Use DRUPAL_CACHE_CUSTOM to disable standard block cache and
- * implement
+ * @defgroup block_caching Block Caching
+ * @{
+ * Constants that define each block's caching state.
+ *
+ * Modules specify how their blocks can be cached in their hook_block_info()
+ * implementations. Caching can be turned off (DRUPAL_NO_CACHE), managed by the
+ * module declaring the block (DRUPAL_CACHE_CUSTOM), or managed by the core
+ * Block module. If the Block module is managing the cache, you can specify that
+ * the block is the same for every page and user (DRUPAL_CACHE_GLOBAL), or that
+ * it can change depending on the page (DRUPAL_CACHE_PER_PAGE) or by user
+ * (DRUPAL_CACHE_PER_ROLE or DRUPAL_CACHE_PER_USER). Page and user settings can
+ * be combined with a bitwise-binary or operator; for example,
+ * DRUPAL_CACHE_PER_ROLE | DRUPAL_CACHE_PER_PAGE means that the block can change
+ * depending on the user role or page it is on.
  *
  * The block cache is cleared in cache_clear_all(), and uses the same clearing
  * policy than page cache (node, comment, user, taxonomy added or updated...).
@@ -123,9 +129,8 @@ define('DRUPAL_NO_CACHE', -1);
 /**
  * The block is handling its own caching in its hook_block_view().
  *
- * From the perspective of the block cache system, this is equivalent to
- * DRUPAL_NO_CACHE. Useful when time based expiration is needed or a site uses
- * a node access which invalidates standard block cache.
+ * This setting is useful when time based expiration is needed or a site uses a
+ * node access which invalidates standard block cache.
  */
 define('DRUPAL_CACHE_CUSTOM', -2);
 
@@ -155,6 +160,10 @@ define('DRUPAL_CACHE_PER_PAGE', 0x0004);
  */
 define('DRUPAL_CACHE_GLOBAL', 0x0008);
 
+/**
+ * @} End of "defgroup block_caching".
+ */
+
 /**
  * Adds content to a specified region.
  *
@@ -199,7 +208,7 @@ function drupal_get_region_content($region = NULL, $delimiter = ' ') {
 }
 
 /**
- * Gets the name of the currently active install profile.
+ * Gets the name of the currently active installation profile.
  *
  * When this function is called during Drupal's initial installation process,
  * the name of the profile that's about to be installed is stored in the global
@@ -208,7 +217,7 @@ function drupal_get_region_content($region = NULL, $delimiter = ' ') {
  * variable_get() to determine what one is active.
  *
  * @return $profile
- *   The name of the install profile.
+ *   The name of the installation profile.
  */
 function drupal_get_profile() {
   global $install_state;
@@ -443,7 +452,7 @@ function drupal_get_query_parameters(array $query = NULL, array $exclude = array
  *   The query string to split.
  *
  * @return
- *   An array of url decoded couples $param_name => $value.
+ *   An array of URL decoded couples $param_name => $value.
  */
 function drupal_get_query_array($query) {
   $result = array();
@@ -505,6 +514,12 @@ function drupal_http_build_query(array $query, $parent = '') {
  * previous request, that destination is returned. As such, a destination can
  * persist across multiple pages.
  *
+ * @return
+ *   An associative array containing the key:
+ *   - destination: The path provided via the destination query string or, if
+ *     not available, the current path.
+ *
+ * @see current_path()
  * @see drupal_goto()
  */
 function drupal_get_destination() {
@@ -798,10 +813,51 @@ function drupal_http_request($url, array $options = array()) {
     'timeout' => 30.0,
     'context' => NULL,
   );
+
+  // Merge the default headers.
+  $options['headers'] += array(
+    'User-Agent' => 'Drupal (+http://drupal.org/)',
+  );
+
   // stream_socket_client() requires timeout to be a float.
   $options['timeout'] = (float) $options['timeout'];
 
+  // Use a proxy if one is defined and the host is not on the excluded list.
+  $proxy_server = variable_get('proxy_server', '');
+  if ($proxy_server && _drupal_http_use_proxy($uri['host'])) {
+    // Set the scheme so we open a socket to the proxy server.
+    $uri['scheme'] = 'proxy';
+    // Set the path to be the full URL.
+    $uri['path'] = $url;
+    // Since the URL is passed as the path, we won't use the parsed query.
+    unset($uri['query']);
+
+    // Add in username and password to Proxy-Authorization header if needed.
+    if ($proxy_username = variable_get('proxy_username', '')) {
+      $proxy_password = variable_get('proxy_password', '');
+      $options['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($proxy_username . (!empty($proxy_password) ? ":" . $proxy_password : ''));
+    }
+    // Some proxies reject requests with any User-Agent headers, while others
+    // require a specific one.
+    $proxy_user_agent = variable_get('proxy_user_agent', '');
+    // The default value matches neither condition.
+    if ($proxy_user_agent === NULL) {
+      unset($options['headers']['User-Agent']);
+    }
+    elseif ($proxy_user_agent) {
+      $options['headers']['User-Agent'] = $proxy_user_agent;
+    }
+  }
+
   switch ($uri['scheme']) {
+    case 'proxy':
+      // Make the socket connection to a proxy server.
+      $socket = 'tcp://' . $proxy_server . ':' . variable_get('proxy_port', 8080);
+      // The Host header still needs to match the real request.
+      $options['headers']['Host'] = $uri['host'];
+      $options['headers']['Host'] .= isset($uri['port']) && $uri['port'] != 80 ? ':' . $uri['port'] : '';
+      break;
+
     case 'http':
     case 'feed':
       $port = isset($uri['port']) ? $uri['port'] : 80;
@@ -811,12 +867,14 @@ function drupal_http_request($url, array $options = array()) {
       // checking the host that do not take into account the port number.
       $options['headers']['Host'] = $uri['host'] . ($port != 80 ? ':' . $port : '');
       break;
+
     case 'https':
       // Note: Only works when PHP is compiled with OpenSSL support.
       $port = isset($uri['port']) ? $uri['port'] : 443;
       $socket = 'ssl://' . $uri['host'] . ':' . $port;
       $options['headers']['Host'] = $uri['host'] . ($port != 443 ? ':' . $port : '');
       break;
+
     default:
       $result->error = 'invalid schema ' . $uri['scheme'];
       $result->code = -1003;
@@ -853,11 +911,6 @@ function drupal_http_request($url, array $options = array()) {
     $path .= '?' . $uri['query'];
   }
 
-  // Merge the default headers.
-  $options['headers'] += array(
-    'User-Agent' => 'Drupal (+http://drupal.org/)',
-  );
-
   // Only add Content-Length if we actually have any content or if it is a POST
   // or PUT request. Some non-standard servers get confused by Content-Length in
   // at least HEAD/GET requests, and Squid always requires Content-Length in
@@ -1028,6 +1081,18 @@ function drupal_http_request($url, array $options = array()) {
 
   return $result;
 }
+
+/**
+ * Helper function for determining hosts excluded from needing a proxy.
+ *
+ * @return
+ *   TRUE if a proxy should be used for this host.
+ */
+function _drupal_http_use_proxy($host) {
+  $proxy_exceptions = variable_get('proxy_exceptions', array('localhost', '127.0.0.1'));
+  return !in_array(strtolower($host), $proxy_exceptions, TRUE);
+}
+
 /**
  * @} End of "HTTP handling".
  */
@@ -1701,7 +1766,7 @@ function format_xml_elements($array) {
  *   $output = format_plural($update_count,
  *     'Changed the content type of 1 post from %old-type to %new-type.',
  *     'Changed the content type of @count posts from %old-type to %new-type.',
- *     array('%old-type' => $info->old_type, '%new-type' => $info->new_type)));
+ *     array('%old-type' => $info->old_type, '%new-type' => $info->new_type));
  * @endcode
  *
  * @param $count
@@ -2079,7 +2144,7 @@ function format_username($account) {
  *     for the URL. If $options['language'] is omitted, the global $language_url
  *     will be used.
  *   - 'https': Whether this URL should point to a secure location. If not
- *     defined, the current scheme is used, so the user stays on http or https
+ *     defined, the current scheme is used, so the user stays on HTTP or HTTPS
  *     respectively. TRUE enforces HTTPS and FALSE enforces HTTP, but HTTPS can
  *     only be enforced when the variable 'https' is set to TRUE.
  *   - 'base_url': Only used internally, to modify the base URL when a language
@@ -2309,21 +2374,22 @@ function drupal_attributes(array $attributes = array()) {
 /**
  * Formats an internal or external URL link as an HTML anchor tag.
  *
- * This function correctly handles aliased paths, and adds an 'active' class
+ * This function correctly handles aliased paths and adds an 'active' class
  * attribute to links that point to the current page (for theming), so all
  * internal links output by modules should be generated by this function if
  * possible.
  *
- * @param $text
- *   The link text for the anchor tag.
- * @param $path
+ * @param string $text
+ *   The translated link text for the anchor tag.
+ * @param string $path
  *   The internal path or external URL being linked to, such as "node/34" or
  *   "http://example.com/foo". After the url() function is called to construct
  *   the URL from $path and $options, the resulting URL is passed through
  *   check_plain() before it is inserted into the HTML anchor tag, to ensure
  *   well-formed HTML. See url() for more information and notes.
  * @param array $options
- *   An associative array of additional options, with the following elements:
+ *   An associative array of additional options. Defaults to an empty array. It
+ *   may contain the following elements.
  *   - 'attributes': An associative array of HTML attributes to apply to the
  *     anchor tag. If element 'class' is included, it must be an array; 'title'
  *     must be a string; other elements are more flexible, as they just need
@@ -2339,8 +2405,10 @@ function drupal_attributes(array $attributes = array()) {
  *     well as the path must match). This element is also used by url().
  *   - Additional $options elements used by the url() function.
  *
- * @return
+ * @return string
  *   An HTML string containing a link to the given path.
+ *
+ * @see url()
  */
 function l($text, $path, array $options = array()) {
   global $language_url;
@@ -3927,7 +3995,8 @@ function drupal_region_class($region) {
  * actually needed.
  *
  * @param $data
- *   (optional) If given, the value depends on the $options parameter:
+ *   (optional) If given, the value depends on the $options parameter, or
+ *   $options['type'] if $options is passed as an associative array:
  *   - 'file': Path to the file relative to base_path().
  *   - 'inline': The JavaScript code that should be placed in the given scope.
  *   - 'external': The absolute path to an external JavaScript file that is not
@@ -5114,6 +5183,7 @@ function drupal_cron_run() {
   @ignore_user_abort(TRUE);
 
   // Prevent session information from being saved while cron is running.
+  $original_session_saving = drupal_save_session();
   drupal_save_session(FALSE);
 
   // Force the current user to anonymous to ensure consistent permissions on
@@ -5176,7 +5246,7 @@ function drupal_cron_run() {
   }
   // Restore the user.
   $GLOBALS['user'] = $original_user;
-  drupal_save_session(TRUE);
+  drupal_save_session($original_session_saving);
 
   return $return;
 }
@@ -5208,7 +5278,7 @@ function drupal_cron_cleanup() {
  * drupal_system_listing("/\.module$/", "modules", 'name', 0);
  * @endcode
  * this function will search the site-wide modules directory (i.e., /modules/),
- * your install profile's directory (i.e.,
+ * your installation profile's directory (i.e.,
  * /profiles/your_site_profile/modules/), the all-sites directory (i.e.,
  * /sites/all/modules/), and your site-specific directory (i.e.,
  * /sites/your_site_dir/modules/), in that order, and return information about
@@ -7449,12 +7519,12 @@ function drupal_check_incompatibility($v, $current_version) {
 /**
  * Get the entity info array of an entity type.
  *
- * @see hook_entity_info()
- * @see hook_entity_info_alter()
- *
  * @param $entity_type
  *   The entity type, e.g. node, for which the info shall be returned, or NULL
  *   to return an array with info about all types.
+ *
+ * @see hook_entity_info()
+ * @see hook_entity_info_alter()
  */
 function entity_get_info($entity_type = NULL) {
   global $language;
@@ -7542,12 +7612,13 @@ function entity_info_cache_clear() {
  *   The entity type; e.g. 'node' or 'user'.
  * @param $entity
  *   The entity from which to extract values.
+ *
  * @return
  *   A numerically indexed array (not a hash table) containing these
  *   elements:
- *   0: primary id of the entity
- *   1: revision id of the entity, or NULL if $entity_type is not versioned
- *   2: bundle name of the entity
+ *   - 0: Primary ID of the entity.
+ *   - 1: Revision ID of the entity, or NULL if $entity_type is not versioned.
+ *   - 2: Bundle name of the entity, or NULL if $entity_type has no bundles.
  */
 function entity_extract_ids($entity_type, $entity) {
   $info = entity_get_info($entity_type);
@@ -7580,13 +7651,12 @@ function entity_extract_ids($entity_type, $entity) {
  * @param $entity_type
  *   The entity type; e.g. 'node' or 'user'.
  * @param $ids
- *   A numerically indexed array, as returned by entity_extract_ids(),
- *   containing these elements:
- *   0: primary id of the entity
- *   1: revision id of the entity, or NULL if $entity_type is not versioned
- *   2: bundle name of the entity, or NULL if $entity_type has no bundles
+ *   A numerically indexed array, as returned by entity_extract_ids().
+ *
  * @return
  *   An entity structure, initialized with the ids provided.
+ *
+ * @see entity_extract_ids()
  */
 function entity_create_stub_entity($entity_type, $ids) {
   $entity = new stdClass();
@@ -7616,11 +7686,6 @@ function entity_create_stub_entity($entity_type, $ids) {
  * DrupalDefaultEntityController class. See node_entity_info() and the
  * NodeController in node.module as an example.
  *
- * @see hook_entity_info()
- * @see DrupalEntityControllerInterface
- * @see DrupalDefaultEntityController
- * @see EntityFieldQuery
- *
  * @param $entity_type
  *   The entity type to load, e.g. node or user.
  * @param $ids
@@ -7638,6 +7703,11 @@ function entity_create_stub_entity($entity_type, $ids) {
  *   found, an empty array is returned.
  *
  * @todo Remove $conditions in Drupal 8.
+ *
+ * @see hook_entity_info()
+ * @see DrupalEntityControllerInterface
+ * @see DrupalDefaultEntityController
+ * @see EntityFieldQuery
  */
 function entity_load($entity_type, $ids = FALSE, $conditions = array(), $reset = FALSE) {
   if ($reset) {
@@ -7657,7 +7727,7 @@ function entity_load($entity_type, $ids = FALSE, $conditions = array(), $reset =
  * @param $entity_type
  *   The entity type to load, e.g. node or user.
  * @param $id
- *   The id of the entity to load.
+ *   The ID of the entity to load.
  *
  * @return
  *   The unchanged entity, or FALSE if the entity cannot be loaded.
@@ -7694,7 +7764,6 @@ function entity_get_controller($entity_type) {
  * recursion. By convention, entity_prepare_view() is called after
  * field_attach_prepare_view() to allow entity level hooks to act on content
  * loaded by field API.
- * @see hook_entity_prepare_view()
  *
  * @param $entity_type
  *   The type of entity, i.e. 'node', 'user'.
@@ -7703,6 +7772,8 @@ function entity_get_controller($entity_type) {
  * @param $langcode
  *   (optional) A language code to be used for rendering. Defaults to the global
  *   content language of the current request.
+ *
+ * @see hook_entity_prepare_view()
  */
 function entity_prepare_view($entity_type, $entities, $langcode = NULL) {
   if (!isset($langcode)) {
@@ -7729,16 +7800,16 @@ function entity_prepare_view($entity_type, $entities, $langcode = NULL) {
 }
 
 /**
- * Returns the uri elements of an entity.
+ * Returns the URI elements of an entity.
  *
  * @param $entity_type
  *   The entity type; e.g. 'node' or 'user'.
  * @param $entity
  *   The entity for which to generate a path.
  * @return
- *   An array containing the 'path' and 'options' keys used to build the uri of
+ *   An array containing the 'path' and 'options' keys used to build the URI of
  *   the entity, and matching the signature of url(). NULL if the entity has no
- *   uri of its own.
+ *   URI of its own.
  */
 function entity_uri($entity_type, $entity) {
   $info = entity_get_info($entity_type);
@@ -7833,7 +7904,7 @@ function entity_language($entity_type, $entity) {
 }
 
 /**
- * Helper function for attaching field API validation to entity forms.
+ * Attaches field API validation to entity forms.
  */
 function entity_form_field_validate($entity_type, $form, &$form_state) {
   // All field attach API functions act on an entity object, but during form
@@ -7846,7 +7917,7 @@ function entity_form_field_validate($entity_type, $form, &$form_state) {
 }
 
 /**
- * Helper function for copying submitted values to entity properties for simple entity forms.
+ * Copies submitted values to entity properties for simple entity forms.
  *
  * During the submission handling of an entity form's "Save", "Preview", and
  * possibly other buttons, the form state's entity needs to be updated with the

+ 2 - 2
includes/database/database.inc

@@ -167,7 +167,7 @@
  * }
  * @endcode
  *
- * @link http://drupal.org/developing/api/database
+ * @link http://drupal.org/developing/api/database @endlink
  */
 
 
@@ -2769,7 +2769,7 @@ function _db_create_keys_sql($spec) {
  * Renames a table.
  *
  * @param $table
- *   The table to be renamed.
+ *   The current name of the table to be renamed.
  * @param $new_name
  *   The new name for the table.
  */

+ 6 - 4
includes/database/log.inc

@@ -128,9 +128,10 @@ class DatabaseLog {
    * Determine the routine that called this query.
    *
    * We define "the routine that called this query" as the first entry in
-   * the call stack that is not inside includes/database. That makes the
-   * climbing logic very simple, and handles the variable stack depth caused
-   * by the query builders.
+   * the call stack that is not inside includes/database and does have a file
+   * (which excludes call_user_func_array(), anonymous functions and similar).
+   * That makes the climbing logic very simple, and handles the variable stack
+   * depth caused by the query builders.
    *
    * @link http://www.php.net/debug_backtrace
    * @return
@@ -144,7 +145,8 @@ class DatabaseLog {
     $stack = debug_backtrace();
     $stack_count = count($stack);
     for ($i = 0; $i < $stack_count; ++$i) {
-      if (strpos($stack[$i]['file'], 'includes' . DIRECTORY_SEPARATOR . 'database') === FALSE) {
+      if (!empty($stack[$i]['file']) && strpos($stack[$i]['file'], 'includes' . DIRECTORY_SEPARATOR . 'database') === FALSE) {
+        $stack[$i] += array('args' => array());
         return array(
           'file' => $stack[$i]['file'],
           'line' => $stack[$i]['line'],

+ 11 - 0
includes/database/pgsql/database.inc

@@ -74,6 +74,17 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
     }
   }
 
+  public function prepareQuery($query) {
+    // mapConditionOperator converts LIKE operations to ILIKE for consistency
+    // with MySQL. However, Postgres does not support ILIKE on bytea (blobs)
+    // fields.
+    // To make the ILIKE operator work, we type-cast bytea fields into text.
+    // @todo This workaround only affects bytea fields, but the involved field
+    //   types involved in the query are unknown, so there is no way to
+    //   conditionally execute this for affected queries only.
+    return parent::prepareQuery(preg_replace('/ ([^ ]+) +(I*LIKE|NOT +I*LIKE) /i', ' ${1}::text ${2} ', $query));
+  }
+
   public function query($query, array $args = array(), $options = array()) {
 
     $options += $this->defaultOptions();

+ 10 - 21
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])) {
@@ -308,6 +296,7 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
 
   /**
    * Attaches data to entities upon loading.
+   *
    * This will attach fields, if the entity is fieldable. It calls
    * hook_entity_load() for modules which need to add data to all entities.
    * It also calls hook_TYPE_load() on the loaded entities. For example
@@ -427,13 +416,14 @@ class EntityFieldQueryException extends Exception {}
  * an EntityFieldQueryException will be raised if an unsupported condition is
  * specified or if the query has field conditions or sorts that are stored in
  * different field storage engines. However, this logic can be overridden in
- * hook_entity_query().
+ * hook_entity_query_alter().
  *
  * Also note that this query does not automatically respect entity access
  * restrictions. Node access control is performed by the SQL storage engine but
  * other storage engines might not do this.
  */
 class EntityFieldQuery {
+
   /**
    * Indicates that both deleted and non-deleted fields should be returned.
    *
@@ -606,9 +596,7 @@ class EntityFieldQuery {
    *
    * 'bundle', 'revision_id' and 'entity_id' have no such restrictions.
    *
-   * Note: The "comment" and "taxonomy_term" entity types don't support bundle
-   * conditions. For "taxonomy_term", propertyCondition('vid') can be used
-   * instead.
+   * Note: The "comment" entity type does not support bundle conditions.
    *
    * @param $name
    *   'entity_type', 'bundle', 'revision_id' or 'entity_id'.
@@ -970,7 +958,7 @@ class EntityFieldQuery {
   }
 
   /**
-   * Enable a pager for the query.
+   * Enables a pager for the query.
    *
    * @param $limit
    *   An integer specifying the number of elements per page.  If passed a false
@@ -998,10 +986,11 @@ class EntityFieldQuery {
   }
 
   /**
-   * Enable sortable tables for this query.
+   * Enables sortable tables for this query.
    *
    * @param $headers
-   *   An EFQ Header array based on which the order clause is added to the query.
+   *   An EFQ Header array based on which the order clause is added to the
+   *   query.
    *
    * @return EntityFieldQuery
    *   The called object.
@@ -1284,7 +1273,7 @@ class EntityFieldQuery {
   }
 
   /**
-   * Get the total number of results and initialize a pager for the query.
+   * Gets the total number of results and initializes a pager for the query.
    *
    * The pager can be disabled by either setting the pager limit to 0, or by
    * setting this query to be a count query.
@@ -1371,6 +1360,6 @@ class EntityFieldQuery {
 }
 
 /**
- * Exception thrown when a malformed entity is passed.
+ * Defines an exception thrown when a malformed entity is passed.
  */
 class EntityMalformedException extends Exception { }

+ 0 - 15
includes/errors.inc

@@ -5,21 +5,6 @@
  * Functions for error handling.
  */
 
-/**
- * Error reporting level: display no errors.
- */
-define('ERROR_REPORTING_HIDE', 0);
-
-/**
- * Error reporting level: display errors and warnings.
- */
-define('ERROR_REPORTING_DISPLAY_SOME', 1);
-
-/**
- * Error reporting level: display all messages.
- */
-define('ERROR_REPORTING_DISPLAY_ALL', 2);
-
 /**
  * Maps PHP error constants to watchdog severity levels.
  *

+ 4 - 4
includes/file.inc

@@ -398,8 +398,8 @@ function file_create_url($uri) {
     }
   }
   elseif ($scheme == 'http' || $scheme == 'https') {
-    // Check for http so that we don't have to implement getExternalUrl() for
-    // the http wrapper.
+    // Check for HTTP so that we don't have to implement getExternalUrl() for
+    // the HTTP wrapper.
     return $uri;
   }
   else {
@@ -2236,7 +2236,7 @@ function drupal_realpath($uri) {
   if ($wrapper = file_stream_wrapper_get_instance_by_uri($uri)) {
     return $wrapper->realpath();
   }
-  // Check that the uri has a value. There is a bug in PHP 5.2 on *BSD systems
+  // Check that the URI has a value. There is a bug in PHP 5.2 on *BSD systems
   // that makes realpath not return FALSE as expected when passing an empty
   // variable.
   // @todo Remove when Drupal drops support for PHP 5.2.
@@ -2489,7 +2489,7 @@ function file_get_content_headers($file) {
   }
 
   return array(
-    'Content-Type' => $type . '; name="' . $name . '"',
+    'Content-Type' => $type,
     'Content-Length' => $file->filesize,
     'Content-Disposition' => $disposition . '; filename="' . $name . '"',
     'Cache-Control' => 'private',

+ 1 - 1
includes/filetransfer/filetransfer.inc

@@ -381,7 +381,7 @@ interface FileTransferChmodInterface {
    * @param string $path
    *   Path to change permissions of.
    * @param long $mode
-   *   @see http://php.net/chmod
+   *   The new file permission mode to be passed to chmod().
    * @param boolean $recursive
    *   Pass TRUE to recursively chmod the entire directory specified in $path.
    */

+ 106 - 60
includes/form.inc

@@ -78,7 +78,7 @@
  * the elements and properties of the form. For information on the array
  * components and format, and more detailed explanations of the Form API
  * workflow, see the
- * @link http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html Form API reference @endlink
+ * @link forms_api_reference.html Form API reference @endlink
  * and the
  * @link http://drupal.org/node/37775 Form API documentation section. @endlink
  * In addition, there is a set of Form API tutorials in
@@ -215,17 +215,15 @@ function drupal_get_form($form_id) {
  *     set.
  *   - values: An associative array of values submitted to the form. The
  *     validation functions and submit functions use this array for nearly all
- *     their decision making. (Note that
- *     @link http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html/7#tree #tree @endlink
- *     determines whether the values are a flat array or an array whose
- *     structure parallels the $form array.)
- *   - input: The array of values as they were submitted by the user. These are
- *     raw and unvalidated, so should not be used without a thorough
- *     understanding of security implications. In almost all cases, code should
- *     use the data in the 'values' array exclusively. The most common use of
- *     this key is for multi-step forms that need to clear some of the user
- *     input when setting 'rebuild'. The values correspond to $_POST or $_GET,
- *     depending on the 'method' chosen.
+ *     their decision making. (Note that #tree determines whether the values are
+ *     a flat array or an array whose structure parallels the $form array. See
+ *     @link forms_api_reference.html Form API reference @endlink for more
+ *     information.) These are raw and unvalidated, so should not be used
+ *     without a thorough understanding of security implications. In almost all
+ *     cases, code should use the data in the 'values' array exclusively. The
+ *     most common use of this key is for multi-step forms that need to clear
+ *     some of the user input when setting 'rebuild'. The values correspond to
+ *     $_POST or $_GET, depending on the 'method' chosen.
  *   - always_process: If TRUE and the method is GET, a form_id is not
  *     necessary. This should only be used on RESTful GET forms that do NOT
  *     write data, as this could lead to security issues. It is useful so that
@@ -730,7 +728,7 @@ function drupal_retrieve_form($form_id, &$form_state) {
   // the form builder callbacks can be loaded when the form is being rebuilt
   // from cache on a different path (such as 'system/ajax'). See
   // form_get_cache().
-  // $menu_get_item() is not available at installation time.
+  // $menu_get_item() is not available during installation.
   if (!isset($form_state['build_info']['files']['menu']) && !defined('MAINTENANCE_MODE')) {
     $item = menu_get_item();
     if (!empty($item['include_file'])) {
@@ -852,7 +850,10 @@ function drupal_process_form($form_id, &$form, &$form_state) {
     // cache when a form is processed, so scenarios that result in
     // the form being built behind the scenes and again for the
     // browser don't increment all the element IDs needlessly.
-    drupal_static_reset('drupal_html_id');
+    if (!form_get_errors()) {
+      // In case of errors, do not break HTML IDs of other forms.
+      drupal_static_reset('drupal_html_id');
+    }
 
     if ($form_state['submitted'] && !form_get_errors() && !$form_state['rebuild']) {
       // Execute form submit handlers.
@@ -1177,18 +1178,23 @@ function drupal_validate_form($form_id, &$form, &$form_state) {
 /**
  * Redirects the user to a URL after a form has been processed.
  *
- * After a form was executed, the data in $form_state controls whether the form
- * is redirected. By default, we redirect to a new destination page. The path
- * of the destination page can be set in $form_state['redirect'], as either a
- * string containing the destination or an array of arguments compatible with
- * drupal_goto(). If that is not set, the user is redirected to the current
- * page to display a fresh, unpopulated copy of the form.
+ * After a form is submitted and processed, normally the user should be
+ * redirected to a new destination page. This function figures out what that
+ * destination should be, based on the $form_state array and the 'destination'
+ * query string in the request URL, and redirects the user there.
+ *
+ * Usually (for exceptions, see below) $form_state['redirect'] determines where
+ * to redirect the user. This can be set either to a string (the path to
+ * redirect to), or an array of arguments for drupal_goto(). If
+ * $form_state['redirect'] is missing, the user is usually (again, see below for
+ * exceptions) redirected back to the page they came from, where they should see
+ * a fresh, unpopulated copy of the form.
  *
- * For example, to redirect to 'node':
+ * Here is an example of how to set up a form to redirect to the path 'node':
  * @code
  * $form_state['redirect'] = 'node';
  * @endcode
- * Or to redirect to 'node/123?foo=bar#baz':
+ * And here is an example of how to redirect to 'node/123?foo=bar#baz':
  * @code
  * $form_state['redirect'] = array(
  *   'node/123',
@@ -1201,29 +1207,27 @@ function drupal_validate_form($form_id, &$form, &$form_state) {
  * );
  * @endcode
  *
- * There are several triggers that may prevent a redirection though:
- * - If $form_state['redirect'] is FALSE, a form builder function or form
- *   validation/submit handler does not want a user to be redirected, which
- *   means that drupal_goto() is not invoked. For most forms, the redirection
- *   logic will be the same regardless of whether $form_state['redirect'] is
- *   undefined or FALSE. However, in case it was not defined and the current
- *   request contains a 'destination' query string, drupal_goto() will redirect
- *   to that given destination instead. Only setting $form_state['redirect'] to
- *   FALSE will prevent any redirection.
- * - If $form_state['no_redirect'] is TRUE, then the callback that originally
- *   built the form explicitly disallows any redirection, regardless of the
- *   redirection value in $form_state['redirect']. For example, ajax_get_form()
- *   defines $form_state['no_redirect'] when building a form in an Ajax
- *   callback to prevent any redirection. $form_state['no_redirect'] should NOT
- *   be altered by form builder functions or form validation/submit handlers.
+ * There are several exceptions to the "usual" behavior described above:
  * - If $form_state['programmed'] is TRUE, the form submission was usually
  *   invoked via drupal_form_submit(), so any redirection would break the script
- *   that invoked drupal_form_submit().
- * - If $form_state['rebuild'] is TRUE, the form needs to be rebuilt without
- *   redirection.
+ *   that invoked drupal_form_submit() and no redirection is done.
+ * - If $form_state['rebuild'] is TRUE, the form is being rebuilt, and no
+ *   redirection is done.
+ * - If $form_state['no_redirect'] is TRUE, redirection is disabled. This is
+ *   set, for instance, by ajax_get_form() to prevent redirection in Ajax
+ *   callbacks. $form_state['no_redirect'] should never be set or altered by
+ *   form builder functions or form validation/submit handlers.
+ * - If $form_state['redirect'] is set to FALSE, redirection is disabled.
+ * - If none of the above conditions has prevented redirection, then the
+ *   redirect is accomplished by calling drupal_goto(), passing in the value of
+ *   $form_state['redirect'] if it is set, or the current path if it is
+ *   not. drupal_goto() preferentially uses the value of $_GET['destination']
+ *   (the 'destination' URL query string) if it is present, so this will
+ *   override any values set by $form_state['redirect']. Note that during
+ *   installation, install_goto() is called in place of drupal_goto().
  *
  * @param $form_state
- *   A keyed array containing the current state of the form.
+ *   An associative array containing the current state of the form.
  *
  * @see drupal_process_form()
  * @see drupal_build_form()
@@ -1255,7 +1259,7 @@ function drupal_redirect_form($form_state) {
         $function($form_state['redirect']);
       }
     }
-    drupal_goto($_GET['q']);
+    drupal_goto(current_path(), array('query' => drupal_get_query_parameters()));
   }
 }
 
@@ -3251,21 +3255,6 @@ function theme_container($variables) {
 /**
  * Returns HTML for a table with radio buttons or checkboxes.
  *
- * An example of per-row options:
- * @code
- * $options = array();
- * $options[0]['title'] = "A red row"
- * $options[0]['#attributes'] = array ('class' => array('red-row'));
- * $options[1]['title'] = "A blue row"
- * $options[1]['#attributes'] = array ('class' => array('blue-row'));
- *
- * $form['myselector'] = array (
- * '#type' => 'tableselect',
- * '#title' => 'My Selector'
- * '#options' => $options,
- * );
- * @endcode
- *
  * @param $variables
  *   An associative array containing:
  *   - element: An associative array containing the properties and children of
@@ -3273,7 +3262,35 @@ function theme_container($variables) {
  *     and #js_select. The #options property is an array of selection options;
  *     each array element of #options is an array of properties. These
  *     properties can include #attributes, which is added to the
- *     table row's HTML attributes; see theme_table().
+ *     table row's HTML attributes; see theme_table(). An example of per-row
+ *     options:
+ *     @code
+ *     $options = array(
+ *       array(
+ *         'title' => 'How to Learn Drupal',
+ *         'content_type' => 'Article',
+ *         'status' => 'published',
+ *         '#attributes' => array('class' => array('article-row')),
+ *       ),
+ *       array(
+ *         'title' => 'Privacy Policy',
+ *         'content_type' => 'Page',
+ *         'status' => 'published',
+ *         '#attributes' => array('class' => array('page-row')),
+ *       ),
+ *     );
+ *     $header = array(
+ *       'title' => t('Title'),
+ *       'content_type' => t('Content type'),
+ *       'status' => t('Status'),
+ *     );
+ *     $form['table'] = array(
+ *       '#type' => 'tableselect',
+ *       '#header' => $header,
+ *       '#options' => $options,
+ *       '#empty' => t('No content available.'),
+ *     );
+ *     @endcode
  *
  * @ingroup themeable
  */
@@ -3645,6 +3662,35 @@ 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.
@@ -4153,7 +4199,7 @@ function _form_set_class(&$element, $class = array()) {
   if (!empty($element['#required'])) {
     $element['#attributes']['class'][] = 'required';
   }
-  if (isset($element['#parents']) && form_get_error($element)) {
+  if (isset($element['#parents']) && form_get_error($element) !== NULL) {
     $element['#attributes']['class'][] = 'error';
   }
 }
@@ -4363,7 +4409,7 @@ function batch_set($batch_definition) {
     }
 
     // Base and default properties for the batch set.
-    // Use get_t() to allow batches at install time.
+    // Use get_t() to allow batches during installation.
     $t = get_t();
     $init = array(
       'sandbox' => array(),

+ 9 - 10
includes/image.inc

@@ -34,7 +34,7 @@
  */
 
 /**
- * Return a list of available toolkits.
+ * Gets a list of available toolkits.
  *
  * @return
  *   An array with the toolkit names as keys and the descriptions as values.
@@ -55,7 +55,7 @@ function image_get_available_toolkits() {
 }
 
 /**
- * Retrieve the name of the currently used toolkit.
+ * Gets the name of the currently used toolkit.
  *
  * @return
  *   String containing the name of the selected toolkit, or FALSE on error.
@@ -101,7 +101,7 @@ function image_toolkit_invoke($method, stdClass $image, array $params = array())
 }
 
 /**
- * Get details about an image.
+ * Gets details about an image.
  *
  * Drupal supports GIF, JPG and PNG file formats when used with the GD
  * toolkit, and may support others, depending on which toolkits are
@@ -261,7 +261,7 @@ function image_scale(stdClass $image, $width = NULL, $height = NULL, $upscale =
 }
 
 /**
- * Resize an image to the given dimensions (ignoring aspect ratio).
+ * Resizes an image to the given dimensions (ignoring aspect ratio).
  *
  * @param $image
  *   An image object returned by image_load().
@@ -284,7 +284,7 @@ function image_resize(stdClass $image, $width, $height) {
 }
 
 /**
- * Rotate an image by the given number of degrees.
+ * Rotates an image by the given number of degrees.
  *
  * @param $image
  *   An image object returned by image_load().
@@ -308,7 +308,7 @@ function image_rotate(stdClass $image, $degrees, $background = NULL) {
 }
 
 /**
- * Crop an image to the rectangle specified by the given rectangle.
+ * Crops an image to a rectangle specified by the given dimensions.
  *
  * @param $image
  *   An image object returned by image_load().
@@ -340,7 +340,7 @@ function image_crop(stdClass $image, $x, $y, $width, $height) {
 }
 
 /**
- * Convert an image to grayscale.
+ * Converts an image to grayscale.
  *
  * @param $image
  *   An image object returned by image_load().
@@ -355,9 +355,8 @@ function image_desaturate(stdClass $image) {
   return image_toolkit_invoke('desaturate', $image);
 }
 
-
 /**
- * Load an image file and return an image object.
+ * Loads an image file and returns an image object.
  *
  * Any changes to the file are not saved until image_save() is called.
  *
@@ -400,7 +399,7 @@ function image_load($file, $toolkit = FALSE) {
 }
 
 /**
- * Close the image and save the changes to a file.
+ * Closes the image and saves the changes to a file.
  *
  * @param $image
  *   An image object returned by image_load(). The object's 'info' property

+ 53 - 38
includes/install.core.inc

@@ -6,8 +6,7 @@
  */
 
 /**
- * Global flag to indicate that a task should not be run during the current
- * installation request.
+ * Do not run the task during the current installation request.
  *
  * This can be used to skip running an installation task when certain
  * conditions are met, even though the task may still show on the list of
@@ -20,8 +19,7 @@
 define('INSTALL_TASK_SKIP', 1);
 
 /**
- * Global flag to indicate that a task should be run on each installation
- * request that reaches it.
+ * Run the task on each installation request until the database is set up.
  *
  * This is primarily used by the Drupal installer for bootstrap-related tasks.
  */
@@ -200,7 +198,7 @@ function install_state_defaults() {
 }
 
 /**
- * Begin an installation request, modifying the installation state as needed.
+ * Begins an installation request, modifying the installation state as needed.
  *
  * This function performs commands that must run at the beginning of every page
  * request. It throws an exception if the installation should not proceed.
@@ -524,7 +522,7 @@ function install_tasks($install_state) {
   $needs_translations = count($install_state['locales']) > 1 && !empty($install_state['parameters']['locale']) && $install_state['parameters']['locale'] != 'en';
 
   // Start with the core installation tasks that run before handing control
-  // to the install profile.
+  // to the installation profile.
   $tasks = array(
     'install_select_profile' => array(
       'display_name' => st('Choose profile'),
@@ -708,7 +706,7 @@ function install_display_output($output, $install_state) {
 }
 
 /**
- * Installation task; verify the requirements for installing Drupal.
+ * Verifies the requirements for installing Drupal.
  *
  * @param $install_state
  *   An array of information about the current installation state.
@@ -776,7 +774,7 @@ function install_system_module(&$install_state) {
   // variable_set() can be used now that system.module is installed.
   $modules = $install_state['profile_info']['dependencies'];
 
-  // The install profile is also a module, which needs to be installed
+  // The installation profile is also a module, which needs to be installed
   // after all the dependencies have been installed.
   $modules[] = drupal_get_profile();
 
@@ -785,7 +783,7 @@ function install_system_module(&$install_state) {
 }
 
 /**
- * Verify and return the last installation task that was completed.
+ * Verifies and returns the last installation task that was completed.
  *
  * @return
  *   The last completed task, if there is one. An exception is thrown if Drupal
@@ -829,7 +827,7 @@ function install_verify_settings() {
 }
 
 /**
- * Verify PDO library.
+ * Verifies the PDO library.
  */
 function install_verify_pdo() {
   // PDO was moved to PHP core in 5.2.0, but the old extension (targeting 5.0
@@ -841,15 +839,14 @@ function install_verify_pdo() {
 }
 
 /**
- * Installation task; define a form to configure and rewrite settings.php.
+ * Form constructor for a form to configure and rewrite settings.php.
  *
- * @param $form_state
- *   An associative array containing the current state of the form.
  * @param $install_state
  *   An array of information about the current installation state.
  *
- * @return
- *   The form API definition for the database configuration form.
+ * @see install_settings_form_validate()
+ * @see install_settings_form_submit()
+ * @ingroup forms
  */
 function install_settings_form($form, &$form_state, &$install_state) {
   global $databases;
@@ -912,7 +909,9 @@ function install_settings_form($form, &$form_state, &$install_state) {
 }
 
 /**
- * Form API validate for install_settings form.
+ * Form validation handler for install_settings_form().
+ *
+ * @see install_settings_form_submit()
  */
 function install_settings_form_validate($form, &$form_state) {
   $driver = $form_state['values']['driver'];
@@ -969,7 +968,9 @@ function install_database_errors($database, $settings_file) {
 }
 
 /**
- * Form API submit for install_settings form.
+ * Form submission handler for install_settings_form().
+ *
+ * @see install_settings_form_validate()
  */
 function install_settings_form_submit($form, &$form_state) {
   global $install_state;
@@ -1000,7 +1001,7 @@ function install_find_profiles() {
 }
 
 /**
- * Installation task; select which profile to install.
+ * Selects which profile to install.
  *
  * @param $install_state
  *   An array of information about the current installation state. The chosen
@@ -1040,8 +1041,7 @@ function install_select_profile(&$install_state) {
 }
 
 /**
- * Helper function for automatically selecting an installation profile from a
- * list or from a selection passed in via $_POST.
+ * Selects an installation profile from a list or from a $_POST submission.
  */
 function _install_select_profile($profiles) {
   if (sizeof($profiles) == 0) {
@@ -1064,12 +1064,14 @@ function _install_select_profile($profiles) {
 }
 
 /**
- * Form API array definition for the profile selection form.
+ * Form constructor for the profile selection form.
  *
  * @param $form_state
  *   Array of metadata about state of form processing.
  * @param $profile_files
  *   Array of .profile files, as returned from file_scan_directory().
+ *
+ * @ingroup forms
  */
 function install_select_profile_form($form, &$form_state, $profile_files) {
   $profiles = array();
@@ -1246,7 +1248,9 @@ function install_select_locale(&$install_state) {
 }
 
 /**
- * Form API array definition for language selection.
+ * Form constructor for the language selection form.
+ *
+ * @ingroup forms
  */
 function install_select_locale_form($form, &$form_state, $locales, $profilename) {
   include_once DRUPAL_ROOT . '/includes/iso.inc';
@@ -1296,7 +1300,7 @@ function install_already_done_error() {
 }
 
 /**
- * Installation task; load information about the chosen profile.
+ * Loads information about the chosen profile during installation.
  *
  * @param $install_state
  *   An array of information about the current installation state. The loaded
@@ -1315,7 +1319,7 @@ function install_load_profile(&$install_state) {
 }
 
 /**
- * Installation task; perform a full bootstrap of Drupal.
+ * Performs a full bootstrap of Drupal during installation.
  *
  * @param $install_state
  *   An array of information about the current installation state.
@@ -1325,7 +1329,7 @@ function install_bootstrap_full(&$install_state) {
 }
 
 /**
- * Installation task; install required modules via a batch process.
+ * Installs required modules via a batch process.
  *
  * @param $install_state
  *   An array of information about the current installation state.
@@ -1378,7 +1382,7 @@ function install_profile_modules(&$install_state) {
 }
 
 /**
- * Installation task; import languages via a batch process.
+ * Imports languages via a batch process during installation.
  *
  * @param $install_state
  *   An array of information about the current installation state.
@@ -1412,15 +1416,14 @@ function install_import_locales(&$install_state) {
 }
 
 /**
- * Installation task; configure settings for the new site.
+ * Form constructor for a form to configure the new site.
  *
- * @param $form_state
- *   An associative array containing the current state of the form.
  * @param $install_state
  *   An array of information about the current installation state.
  *
- * @return
- *   The form API definition for the site configuration form.
+ * @see install_configure_form_validate()
+ * @see install_configure_form_submit()
+ * @ingroup forms
  */
 function install_configure_form($form, &$form_state, &$install_state) {
   drupal_set_title(st('Configure site'));
@@ -1443,7 +1446,7 @@ function install_configure_form($form, &$form_state, &$install_state) {
   // Add JavaScript time zone detection.
   drupal_add_js('misc/timezone.js');
   // We add these strings as settings because JavaScript translation does not
-  // work on install time.
+  // work during installation.
   drupal_add_js(array('copyFieldValue' => array('edit-site-mail' => array('edit-account-mail'))), 'setting');
   drupal_add_js('jQuery(function () { Drupal.cleanURLsInstallCheck(); });', 'inline');
   // Add JS to show / hide the 'Email administrator about site updates' elements
@@ -1486,7 +1489,7 @@ function install_import_locales_remaining(&$install_state) {
 }
 
 /**
- * Installation task; perform final steps and display a 'finished' page.
+ * Finishes importing files at end of installation.
  *
  * @param $install_state
  *   An array of information about the current installation state.
@@ -1502,13 +1505,13 @@ function install_finished(&$install_state) {
 
   // Flush all caches to ensure that any full bootstraps during the installer
   // do not leave stale cached data, and that any content types or other items
-  // registered by the install profile are registered correctly.
+  // registered by the installation profile are registered correctly.
   drupal_flush_all_caches();
 
   // Remember the profile which was used.
   variable_set('install_profile', drupal_get_profile());
 
-  // Install profiles are always loaded last
+  // Installation profiles are always loaded last
   db_update('system')
     ->fields(array('weight' => 1000))
     ->condition('type', 'module')
@@ -1673,7 +1676,15 @@ function install_check_requirements($install_state) {
 }
 
 /**
- * Forms API array definition for site configuration.
+ * Form constructor for a site configuration form.
+ *
+ * @param $install_state
+ *   An array of information about the current installation state.
+ *
+ * @see install_configure_form()
+ * @see install_configure_form_validate()
+ * @see install_configure_form_submit()
+ * @ingroup forms
  */
 function _install_configure_form($form, &$form_state, &$install_state) {
   include_once DRUPAL_ROOT . '/includes/locale.inc';
@@ -1786,7 +1797,9 @@ function _install_configure_form($form, &$form_state, &$install_state) {
 }
 
 /**
- * Forms API validate for the site configuration form.
+ * Form validation handler for install_configure_form().
+ *
+ * @see install_configure_form_submit()
  */
 function install_configure_form_validate($form, &$form_state) {
   if ($error = user_validate_name($form_state['values']['account']['name'])) {
@@ -1801,7 +1814,9 @@ function install_configure_form_validate($form, &$form_state) {
 }
 
 /**
- * Forms API submit for the site configuration form.
+ * Form submission handler for install_configure_form().
+ *
+ * @see install_configure_form_validate()
  */
 function install_configure_form_submit($form, &$form_state) {
   global $user;

+ 38 - 25
includes/install.inc

@@ -1,5 +1,10 @@
 <?php
 
+/**
+* @file
+* API functions for installing modules and themes.
+*/
+
 /**
  * Indicates that a module has not been installed yet.
  */
@@ -71,7 +76,7 @@ define('FILE_NOT_WRITABLE', 64);
 define('FILE_NOT_EXECUTABLE', 128);
 
 /**
- * Initialize the update system by loading all installed module's .install files.
+ * Loads .install files for installed modules to initialize the update system.
  */
 function drupal_load_updates() {
   foreach (drupal_get_installed_schema_version(NULL, FALSE, TRUE) as $module => $schema_version) {
@@ -180,11 +185,11 @@ function drupal_set_installed_schema_version($module, $version) {
 }
 
 /**
- * Loads the install profile, extracting its defined distribution name.
+ * Loads the installation profile, extracting its defined distribution name.
  *
  * @return
  *   The distribution name defined in the profile's .info file. Defaults to
- *   "Drupal" if none is explicitly provided by the install profile.
+ *   "Drupal" if none is explicitly provided by the installation profile.
  *
  * @see install_profile_info()
  */
@@ -204,11 +209,12 @@ function drupal_install_profile_distribution_name() {
 }
 
 /**
- * Auto detect the base_url with PHP predefined variables.
+ * Detects the base URL using the PHP $_SERVER variables.
  *
  * @param $file
  *   The name of the file calling this function so we can strip it out of
  *   the URI when generating the base_url.
+ *
  * @return
  *   The auto-detected $base_url that should be configured in settings.php
  */
@@ -223,7 +229,7 @@ function drupal_detect_baseurl($file = 'install.php') {
 }
 
 /**
- * Detect all supported databases that are compiled into PHP.
+ * Detects all supported databases that are compiled into PHP.
  *
  * @return
  *  An array of database types compiled into PHP.
@@ -239,7 +245,7 @@ function drupal_detect_database_types() {
 }
 
 /**
- * Return all supported database installer objects that are compiled into PHP.
+ * Returns all supported database installer objects that are compiled into PHP.
  *
  * @return
  *  An array of database installer objects compiled into PHP.
@@ -576,7 +582,7 @@ class DatabaseTaskException extends Exception {
 }
 
 /**
- * Replace values in settings.php with values in the submitted array.
+ * Replaces values in settings.php with values in the submitted array.
  *
  * @param $settings
  *   An array of settings that need to be updated.
@@ -654,10 +660,11 @@ function drupal_rewrite_settings($settings = array(), $prefix = '') {
 }
 
 /**
- * Verify an install profile for installation.
+ * Verifies an installation profile for installation.
  *
  * @param $install_state
  *   An array of information about the current installation state.
+ *
  * @return
  *   The list of modules to install.
  */
@@ -681,8 +688,8 @@ function drupal_verify_profile($install_state) {
     $present_modules[] = $present_module->name;
   }
 
-  // The install profile is also a module, which needs to be installed after all the other dependencies
-  // have been installed.
+  // The installation profile is also a module, which needs to be installed
+  // after all the other dependencies have been installed.
   $present_modules[] = drupal_get_profile();
 
   // Verify that all of the profile's required modules are present.
@@ -706,7 +713,7 @@ function drupal_verify_profile($install_state) {
 }
 
 /**
- * Callback to install the system module.
+ * Installs the system module.
  *
  * Separated from the installation of other modules so core system
  * functions can be made available while other modules are installed.
@@ -800,7 +807,7 @@ function drupal_uninstall_modules($module_list = array(), $uninstall_dependents
 }
 
 /**
- * Verify the state of the specified file.
+ * Verifies the state of the specified file.
  *
  * @param $file
  *   The file to check for.
@@ -808,6 +815,7 @@ function drupal_uninstall_modules($module_list = array(), $uninstall_dependents
  *   An optional bitmask created from various FILE_* constants.
  * @param $type
  *   The type of file. Can be file (default), dir, or link.
+ *
  * @return
  *   TRUE on success or FALSE on failure. A message is set for the latter.
  */
@@ -879,7 +887,7 @@ function drupal_verify_install_file($file, $mask = NULL, $type = 'file') {
 }
 
 /**
- * Create a directory with specified permissions.
+ * Creates a directory with the specified permissions.
  *
  * @param $file
  *  The name of the directory to create;
@@ -887,6 +895,7 @@ function drupal_verify_install_file($file, $mask = NULL, $type = 'file') {
  *  The permissions of the directory to create.
  * @param $message
  *  (optional) Whether to output messages. Defaults to TRUE.
+ *
  * @return
  *  TRUE/FALSE whether or not the directory was successfully created.
  */
@@ -918,7 +927,7 @@ function drupal_install_mkdir($file, $mask, $message = TRUE) {
 }
 
 /**
- * Attempt to fix file permissions.
+ * Attempts to fix file permissions.
  *
  * The general approach here is that, because we do not know the security
  * setup of the webserver, we apply our permission changes to all three
@@ -935,6 +944,7 @@ function drupal_install_mkdir($file, $mask, $message = TRUE) {
  *  The desired permissions for the file.
  * @param $message
  *  (optional) Whether to output messages. Defaults to TRUE.
+ *
  * @return
  *  TRUE/FALSE whether or not we were able to fix the file's permissions.
  */
@@ -1000,7 +1010,7 @@ function drupal_install_fix_file($file, $mask, $message = TRUE) {
 }
 
 /**
- * Send the user to a different installer page.
+ * Sends the user to a different installer page.
  *
  * This issues an on-site HTTP redirect. Messages (and errors) are erased.
  *
@@ -1078,7 +1088,7 @@ function drupal_requirements_url($severity) {
 }
 
 /**
- * Functional equivalent of t(), used when some systems are not available.
+ * Translates a string when some systems are not available.
  *
  * Used during the install process, when database, theme, and localization
  * system is possibly not yet available.
@@ -1138,12 +1148,12 @@ function st($string, array $args = array(), array $options = array()) {
 }
 
 /**
- * Check an install profile's requirements.
+ * Checks an installation profile's requirements.
  *
  * @param $profile
- *   Name of install profile to check.
+ *   Name of installation profile to check.
  * @return
- *   Array of the install profile's requirements.
+ *   Array of the installation profile's requirements.
  */
 function drupal_check_profile($profile) {
   include_once DRUPAL_ROOT . '/includes/file.inc';
@@ -1169,11 +1179,12 @@ function drupal_check_profile($profile) {
 }
 
 /**
- * Extract highest severity from requirements array.
+ * Extracts the highest severity from the requirements array.
  *
  * @param $requirements
  *   An array of requirements, in the same format as is returned by
  *   hook_requirements().
+ *
  * @return
  *   The highest severity in the array.
  */
@@ -1188,12 +1199,13 @@ function drupal_requirements_severity(&$requirements) {
 }
 
 /**
- * Check a module's requirements.
+ * Checks a module's requirements.
  *
  * @param $module
  *   Machine name of module to check.
+ *
  * @return
- *   TRUE/FALSE depending on the requirements are in place.
+ *   TRUE or FALSE, depending on whether the requirements are met.
  */
 function drupal_check_module($module) {
   module_load_install($module);
@@ -1218,13 +1230,14 @@ function drupal_check_module($module) {
 }
 
 /**
- * Retrieve info about an install profile from its .info file.
+ * Retrieves information about an installation profile from its .info file.
  *
  * The information stored in a profile .info file is similar to that stored in
  * a normal Drupal module .info file. For example:
- * - name: The real name of the install profile for display purposes.
+ * - name: The real name of the installation profile for display purposes.
  * - description: A brief description of the profile.
- * - dependencies: An array of shortnames of other modules this install profile requires.
+ * - dependencies: An array of shortnames of other modules that this install
+ *   profile requires.
  *
  * Additional, less commonly-used information that can appear in a profile.info
  * file but not in a normal Drupal module .info file includes:

+ 1 - 1
includes/iso.inc

@@ -461,7 +461,7 @@ function _locale_get_predefined_list() {
     'tt' => array('Tatar', 'Tatarça'),
     'tw' => array('Twi'),
     'ty' => array('Tahitian'),
-    'ug' => array('Uighur'),
+    'ug' => array('Uyghur'),
     'uk' => array('Ukrainian', 'Українська'),
     'ur' => array('Urdu', /* Left-to-right marker "‭" */ 'اردو', LANGUAGE_RTL),
     'uz' => array('Uzbek', "o'zbek"),

+ 14 - 3
includes/language.inc

@@ -190,6 +190,11 @@ function language_negotiation_get_switch_links($type, $path) {
   $links = FALSE;
   $negotiation = variable_get("language_negotiation_$type", array());
 
+  // Only get the languages if we have more than one.
+  if (count(language_list()) >= 2) {
+    $language = language_initialize($type);
+  }
+
   foreach ($negotiation as $id => $provider) {
     if (isset($provider['callbacks']['switcher'])) {
       if (isset($provider['file'])) {
@@ -199,6 +204,12 @@ function language_negotiation_get_switch_links($type, $path) {
       $callback = $provider['callbacks']['switcher'];
       $result = $callback($type, $path);
 
+      // Add support for WCAG 2.0's Language of Parts to add language identifiers.
+      // http://www.w3.org/TR/UNDERSTANDING-WCAG20/meaning-other-lang-id.html
+      foreach ($result as $langcode => $link) {
+        $result[$langcode]['attributes']['lang'] = $langcode;
+      }
+
       if (!empty($result)) {
         // Allow modules to provide translations for specific links.
         drupal_alter('language_switch_links', $result, $type, $path);
@@ -408,7 +419,7 @@ function language_from_default() {
 }
 
 /**
- * Split the given path into prefix and actual path.
+ * 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.
@@ -440,10 +451,10 @@ function language_url_split_prefix($path, $languages) {
 }
 
 /**
- * Return the possible fallback languages ordered by language weight.
+ * Returns the possible fallback languages ordered by language weight.
  *
  * @param
- *   The language type.
+ *   (optional) The language type. Defaults to LANGUAGE_TYPE_CONTENT.
  *
  * @return
  *   An array of language codes.

+ 15 - 13
includes/mail.inc

@@ -13,7 +13,7 @@
 define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || strpos($_SERVER['SERVER_SOFTWARE'], 'Win32') !== FALSE ? "\r\n" : "\n");
 
 /**
- * Compose and optionally send an e-mail message.
+ * Composes and optionally sends an e-mail message.
  *
  * Sending an e-mail works with defining an e-mail template (subject, text
  * and possibly e-mail headers) and the replacement values to use in the
@@ -191,7 +191,7 @@ function drupal_mail($module, $key, $to, $language, $params = array(), $from = N
 }
 
 /**
- * Returns an object that implements the MailSystemInterface.
+ * Returns an object that implements the MailSystemInterface interface.
  *
  * Allows for one or more custom mail backends to format and send mail messages
  * composed using drupal_mail().
@@ -328,7 +328,7 @@ interface MailSystemInterface {
 }
 
 /**
- * Perform format=flowed soft wrapping for mail (RFC 3676).
+ * Performs format=flowed soft wrapping for mail (RFC 3676).
  *
  * We use delsp=yes wrapping, but only break non-spaced languages when
  * absolutely necessary to avoid compatibility issues.
@@ -340,6 +340,9 @@ interface MailSystemInterface {
  * @param $indent (optional)
  *   A string to indent the text with. Only '>' characters are repeated on
  *   subsequent wrapped lines. Others are replaced by spaces.
+ *
+ * @return
+ *   The content of the email as a string with formatting applied.
  */
 function drupal_wrap_mail($text, $indent = '') {
   // Convert CRLF into LF.
@@ -371,8 +374,7 @@ function drupal_wrap_mail($text, $indent = '') {
 }
 
 /**
- * Transform an HTML string into plain text, preserving the structure of the
- * markup. Useful for preparing the body of a node to be sent by e-mail.
+ * Transforms an HTML string into plain text, preserving its structure.
  *
  * The output will be suitable for use as 'format=flowed; delsp=yes' text
  * (RFC 3676) and can be passed directly to drupal_mail() for sending.
@@ -551,9 +553,9 @@ function drupal_html_to_text($string, $allowed_tags = NULL) {
 }
 
 /**
- * Helper function for array_walk in drupal_wrap_mail().
- *
  * Wraps words on a single line.
+ *
+ * Callback for array_walk() winthin drupal_wrap_mail().
  */
 function _drupal_wrap_mail_line(&$line, $key, $values) {
   // Use soft-breaks only for purely quoted or unindented text.
@@ -563,9 +565,9 @@ function _drupal_wrap_mail_line(&$line, $key, $values) {
 }
 
 /**
- * Helper function for drupal_html_to_text().
- *
  * Keeps track of URLs and replaces them with placeholder tokens.
+ *
+ * Callback for preg_replace_callback() within drupal_html_to_text().
  */
 function _drupal_html_to_mail_urls($match = NULL, $reset = FALSE) {
   global $base_url, $base_path;
@@ -590,18 +592,18 @@ function _drupal_html_to_mail_urls($match = NULL, $reset = FALSE) {
 }
 
 /**
- * Helper function for drupal_wrap_mail() and drupal_html_to_text().
+ * Replaces non-quotation markers from a given piece of indentation with spaces.
  *
- * Replace all non-quotation markers from a given piece of indentation with spaces.
+ * Callback for array_map() within drupal_html_to_text().
  */
 function _drupal_html_to_text_clean($indent) {
   return preg_replace('/[^>]/', ' ', $indent);
 }
 
 /**
- * Helper function for drupal_html_to_text().
+ * Pads the last line with the given character.
  *
- * Pad the last line with the given character.
+ * @see drupal_html_to_text()
  */
 function _drupal_html_to_text_pad($text, $pad, $prefix = '') {
   // Remove last line break.

+ 87 - 72
includes/menu.inc

@@ -417,9 +417,9 @@ function menu_unserialize($data, $map) {
  * @param $path
  *   The path.
  * @param $router_item
- *   The router item. Usually you take a router entry from menu_get_item and
- *   set it back either modified or to a different path. This lets you modify the
- *   navigation block, the page title, the breadcrumb and the page help in one
+ *   The router item. Usually a router entry from menu_get_item() is either
+ *   modified or set to a different path. This allows the navigation block,
+ *   the page title, the breadcrumb, and the page help to be modified in one
  *   call.
  */
 function menu_set_item($path, $router_item) {
@@ -427,7 +427,7 @@ function menu_set_item($path, $router_item) {
 }
 
 /**
- * Get a router item.
+ * Gets a router item.
  *
  * @param $path
  *   The path, for example node/5. The function will find the corresponding
@@ -436,12 +436,13 @@ function menu_set_item($path, $router_item) {
  *   Internal use only.
  *
  * @return
- *   The router item, an associate array corresponding to one row in the
- *   menu_router table. The value of key map holds the loaded objects. The
- *   value of key access is TRUE if the current user can access this page.
- *   The values for key title, page_arguments, access_arguments, and
- *   theme_arguments will be filled in based on the database values and the
- *   objects loaded.
+ *   The router item or, if an error occurs in _menu_translate(), FALSE. A
+ *   router item is an associative array corresponding to one row in the
+ *   menu_router table. The value corresponding to the key 'map' holds the
+ *   loaded objects. The value corresponding to the key 'access' is TRUE if the
+ *   current user can access this page. The values corresponding to the keys
+ *   'title', 'page_arguments', 'access_arguments', and 'theme_arguments' will
+ *   be filled in based on the database values and the objects loaded.
  */
 function menu_get_item($path = NULL, $router_item = NULL) {
   $router_items = &drupal_static(__FUNCTION__);
@@ -606,7 +607,7 @@ function _menu_load_objects(&$item, &$map) {
 }
 
 /**
- * Check access to a menu item using the access callback
+ * Checks access to a menu item using the access callback.
  *
  * @param $item
  *   A menu router or menu link item
@@ -638,7 +639,7 @@ function _menu_check_access(&$item, $map) {
 }
 
 /**
- * Localize the router item title using t() or another callback.
+ * Localizes the router item title using t() or another callback.
  *
  * Translate the title and description to allow storage of English title
  * strings in the database, yet display of them in the language required
@@ -746,7 +747,7 @@ function _menu_item_localize(&$item, $map, $link_translate = FALSE) {
  *   $item['load_functions']. $item['access'] becomes TRUE if the item is
  *   accessible, FALSE otherwise. $item['href'] is set according to the map.
  *   If an error occurs during calling the load_functions (like trying to load
- *   a non existing node) then this function return FALSE.
+ *   a non-existent node) then this function returns FALSE.
  */
 function _menu_translate(&$router_item, $map, $to_arg = FALSE) {
   if ($to_arg && !empty($router_item['to_arg_functions'])) {
@@ -796,14 +797,14 @@ function _menu_translate(&$router_item, $map, $to_arg = FALSE) {
 }
 
 /**
- * This function translates the path elements in the map using any to_arg
- * helper function. These functions take an argument and return an object.
- * See http://drupal.org/node/109153 for more information.
+ * Translates the path elements in the map using any to_arg helper function.
  *
  * @param $map
  *   An array of path arguments (ex: array('node', '5'))
  * @param $to_arg_functions
  *   An array of helper function (ex: array(2 => 'menu_tail_to_arg'))
+ *
+ * @see hook_menu()
  */
 function _menu_link_map_translate(&$map, $to_arg_functions) {
   $to_arg_functions = unserialize($to_arg_functions);
@@ -820,14 +821,14 @@ function _menu_link_map_translate(&$map, $to_arg_functions) {
 }
 
 /**
- * Returns path as one string from the argument we are currently at.
+ * Returns a string containing the path relative to the current index.
  */
 function menu_tail_to_arg($arg, $map, $index) {
   return implode('/', array_slice($map, $index));
 }
 
 /**
- * Loads path as one string from the argument we are currently at.
+ * Loads the path as one string relative to the current index.
  *
  * To use this load function, you must specify the load arguments
  * in the router item as:
@@ -844,8 +845,10 @@ function menu_tail_load($arg, &$map, $index) {
 }
 
 /**
- * This function is similar to _menu_translate() but does link-specific
- * preparation such as always calling to_arg functions
+ * Provides menu link access control, translation, and argument handling.
+ *
+ * This function is similar to _menu_translate(), but it also does
+ * link-specific preparation (such as always calling to_arg() functions).
  *
  * @param $item
  *   A menu link.
@@ -939,7 +942,7 @@ function _menu_link_translate(&$item, $translate = FALSE) {
 }
 
 /**
- * Get a loaded object from a router item.
+ * Gets a loaded object from a router item.
  *
  * menu_get_object() provides access to objects loaded by the current router
  * item. For example, on the page node/%node, the router loads the %node object,
@@ -1079,7 +1082,7 @@ function menu_tree_output($tree) {
 }
 
 /**
- * Get the data structure representing a named menu tree.
+ * Gets the data structure representing a named menu tree.
  *
  * Since this can be the full tree including hidden items, the data returned
  * may be used for generating an an admin interface or a select.
@@ -1147,7 +1150,7 @@ function menu_tree_all_data($menu_name, $link = NULL, $max_depth = NULL) {
 }
 
 /**
- * Set the path for determining the active trail of the specified menu tree.
+ * Sets the path for determining the active trail of the specified menu tree.
  *
  * This path will also affect the breadcrumbs under some circumstances.
  * Breadcrumbs are built using the preferred link returned by
@@ -1172,7 +1175,7 @@ function menu_tree_set_path($menu_name, $path = NULL) {
 }
 
 /**
- * Get the path for determining the active trail of the specified menu tree.
+ * Gets the path for determining the active trail of the specified menu tree.
  *
  * @param $menu_name
  *   The menu name of the requested tree.
@@ -1186,7 +1189,7 @@ function menu_tree_get_path($menu_name) {
 }
 
 /**
- * Get the data structure representing a named menu tree, based on the current page.
+ * Gets the data structure for a named menu tree, based on the current page.
  *
  * The tree order is maintained by storing each parent in an individual
  * field, see http://drupal.org/node/141866 for more.
@@ -1320,7 +1323,7 @@ function menu_tree_page_data($menu_name, $max_depth = NULL, $only_active_trail =
 }
 
 /**
- * Build a menu tree, translate links, and check access.
+ * Builds a menu tree, translates links, and checks access.
  *
  * @param $menu_name
  *   The name of the menu.
@@ -1335,8 +1338,8 @@ function menu_tree_page_data($menu_name, $max_depth = NULL, $only_active_trail =
  *     trail. This option is ignored, if 'expanded' is non-empty. Internally
  *     used for breadcrumbs.
  *   - min_depth: The minimum depth of menu links in the resulting tree.
- *     Defaults to 1, which is the default to build a whole tree for a menu, i.e.
- *     excluding menu container itself.
+ *     Defaults to 1, which is the default to build a whole tree for a menu
+ *     (excluding menu container itself).
  *   - max_depth: The maximum depth of menu links in the resulting tree.
  *   - conditions: An associative array of custom database select query
  *     condition key/value pairs; see _menu_build_tree() for the actual query.
@@ -1353,7 +1356,7 @@ function menu_build_tree($menu_name, array $parameters = array()) {
 }
 
 /**
- * Build a menu tree.
+ * Builds a menu tree.
  *
  * This function may be used build the data for a menu tree only, for example
  * to further massage the data manually before further processing happens.
@@ -1449,7 +1452,7 @@ function _menu_build_tree($menu_name, array $parameters = array()) {
 }
 
 /**
- * Recursive helper function - collect node links.
+ * Collects node links from a given menu tree recursively.
  *
  * @param $tree
  *   The menu tree you wish to collect node links from.
@@ -1472,7 +1475,7 @@ function menu_tree_collect_node_links(&$tree, &$node_links) {
 }
 
 /**
- * Check access and perform other dynamic operations for each link in the tree.
+ * Checks access and performs dynamic operations for each link in the tree.
  *
  * @param $tree
  *   The menu tree you wish to operate on.
@@ -1499,7 +1502,7 @@ function menu_tree_check_access(&$tree, $node_links = array()) {
 }
 
 /**
- * Recursive helper function for menu_tree_check_access()
+ * Sorts the menu tree and recursively checks access for each item.
  */
 function _menu_tree_check_access(&$tree) {
   $new_tree = array();
@@ -1522,7 +1525,7 @@ function _menu_tree_check_access(&$tree) {
 }
 
 /**
- * Builds the data representing a menu tree.
+ * Sorts and returns the built data representing a menu tree.
  *
  * @param $links
  *   A flat array of menu links that are part of the menu. Each array element
@@ -1554,7 +1557,7 @@ function menu_tree_data(array $links, array $parents = array(), $depth = 1) {
 }
 
 /**
- * Recursive helper function to build the data representing a menu tree.
+ * Builds the data representing a menu tree.
  *
  * The function is a bit complex because the rendering of a link depends on
  * the next menu link.
@@ -1589,7 +1592,7 @@ function _menu_tree_data(&$links, $parents, $depth) {
 }
 
 /**
- * Preprocesses the rendered tree for theme_menu_tree().
+ * Implements template_preprocess_HOOK() for theme_menu_tree().
  */
 function template_preprocess_menu_tree(&$variables) {
   $variables['tree'] = $variables['tree']['#children'];
@@ -1783,7 +1786,7 @@ function menu_get_names() {
 }
 
 /**
- * Return an array containing the names of system-defined (default) menus.
+ * Returns an array containing the names of system-defined (default) menus.
  */
 function menu_list_system_menus() {
   return array(
@@ -1795,14 +1798,14 @@ function menu_list_system_menus() {
 }
 
 /**
- * Return an array of links to be rendered as the Main menu.
+ * Returns an array of links to be rendered as the Main menu.
  */
 function menu_main_menu() {
   return menu_navigation_links(variable_get('menu_main_links_source', 'main-menu'));
 }
 
 /**
- * Return an array of links to be rendered as the Secondary links.
+ * Returns an array of links to be rendered as the Secondary links.
  */
 function menu_secondary_menu() {
 
@@ -1817,7 +1820,7 @@ function menu_secondary_menu() {
 }
 
 /**
- * Return an array of links for a navigation menu.
+ * Returns an array of links for a navigation menu.
  *
  * @param $menu_name
  *   The name of the menu.
@@ -2109,14 +2112,12 @@ function menu_local_tasks($level = 0) {
 }
 
 /**
- * Retrieve contextual links for a system object based on registered local tasks.
+ * Retrieves contextual links for a path based on registered local tasks.
  *
  * This leverages the menu system to retrieve the first layer of registered
  * local tasks for a given system path. All local tasks of the tab type
  * MENU_CONTEXT_INLINE are taken into account.
  *
- * @see hook_menu()
- *
  * For example, when considering the following registered local tasks:
  * - node/%node/view (default local task) with no 'context' defined
  * - node/%node/edit with context: MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE
@@ -2144,6 +2145,7 @@ function menu_local_tasks($level = 0) {
  *   A list of menu router items that are local tasks for the passed-in path.
  *
  * @see contextual_links_preprocess()
+ * @see hook_menu()
  */
 function menu_contextual_links($module, $parent_path, $args) {
   static $path_empty = array();
@@ -2237,7 +2239,7 @@ function menu_local_actions() {
 }
 
 /**
- * Returns the router path, or the path of the parent tab of a default local task.
+ * Returns the router path, or the path for a default local task's parent.
  */
 function menu_tab_root_path() {
   $links = menu_local_tasks();
@@ -2258,7 +2260,13 @@ function menu_local_tabs() {
 /**
  * Returns HTML for primary and secondary local tasks.
  *
+ * @param $variables
+ *   An associative array containing:
+ *     - primary: (optional) An array of local tasks (tabs).
+ *     - secondary: (optional) An array of local tasks (tabs).
+ *
  * @ingroup themeable
+ * @see menu_local_tasks()
  */
 function theme_menu_local_tasks(&$variables) {
   $output = '';
@@ -2280,7 +2288,9 @@ function theme_menu_local_tasks(&$variables) {
 }
 
 /**
- * Set (or get) the active menu for the current page - determines the active trail.
+ * Sets (or gets) the active menu for the current page.
+ *
+ * The active menu for the page determines the active trail.
  *
  * @return
  *   An array of menu machine names, in order of preference. The
@@ -2302,17 +2312,17 @@ function menu_set_active_menu_names($menu_names = NULL) {
 }
 
 /**
- * Get the active menu for the current page - determines the active trail.
+ * Gets the active menu for the current page.
  */
 function menu_get_active_menu_names() {
   return menu_set_active_menu_names();
 }
 
 /**
- * Set the active path, which determines which page is loaded.
+ * Sets the active path, which determines which page is loaded.
  *
  * Note that this may not have the desired effect unless invoked very early
- * in the page load, such as during hook_boot, or unless you call
+ * in the page load, such as during hook_boot(), or unless you call
  * menu_execute_active_handler() to generate your page output.
  *
  * @param $path
@@ -2326,7 +2336,7 @@ function menu_set_active_item($path) {
 }
 
 /**
- * Sets the active trail (path to menu tree root) of the current page.
+ * Sets the active trail (path to the menu tree root) of the current page.
  *
  * Any trail set by this function will only be used for functionality that calls
  * menu_get_active_trail(). Drupal core only uses trails set here for
@@ -2416,7 +2426,7 @@ function menu_set_active_trail($new_trail = NULL) {
 }
 
 /**
- * Lookup the preferred menu link for a given system path.
+ * Looks up the preferred menu link for a given system path.
  *
  * @param $path
  *   The path, for example 'node/5'. The function will find the corresponding
@@ -2536,7 +2546,7 @@ function menu_get_active_trail() {
 }
 
 /**
- * Get the breadcrumb for the current page, as determined by the active trail.
+ * Gets the breadcrumb for the current page, as determined by the active trail.
  *
  * @see menu_set_active_trail()
  */
@@ -2587,7 +2597,7 @@ function menu_get_active_breadcrumb() {
 }
 
 /**
- * Get the title of the current page, as determined by the active trail.
+ * Gets the title of the current page, as determined by the active trail.
  */
 function menu_get_active_title() {
   $active_trail = menu_get_active_trail();
@@ -2600,7 +2610,7 @@ function menu_get_active_title() {
 }
 
 /**
- * Get a menu link by its mlid, access checked and link translated for rendering.
+ * Gets a translated, access-checked menu link that is ready for rendering.
  *
  * This function should never be called from within node_load() or any other
  * function used as a menu object load function since an infinite recursion may
@@ -2651,7 +2661,9 @@ function menu_cache_clear($menu_name = 'navigation') {
 }
 
 /**
- * Clears all cached menu data. This should be called any time broad changes
+ * Clears all cached menu data.
+ *
+ * This should be called any time broad changes
  * might have been made to the router items or menu links.
  */
 function menu_cache_clear_all() {
@@ -2672,10 +2684,10 @@ function menu_reset_static_cache() {
 }
 
 /**
- * (Re)populate the database tables used by various menu functions.
+ * Populates the database tables used by various menu functions.
  *
  * This function will clear and populate the {menu_router} table, add entries
- * to {menu_links} for new router items, then remove stale items from
+ * to {menu_links} for new router items, and then remove stale items from
  * {menu_links}. If called from update.php or install.php, it will also
  * schedule a call to itself on the first real page load from
  * menu_execute_active_handler(), because the maintenance page environment
@@ -2721,7 +2733,7 @@ function menu_rebuild() {
 }
 
 /**
- * Collect and alter the menu definitions.
+ * Collects and alters the menu definitions.
  */
 function menu_router_build() {
   // We need to manually call each module so that we can know which module
@@ -2745,7 +2757,7 @@ function menu_router_build() {
 }
 
 /**
- * Helper function to store the menu router if we have it in memory.
+ * Stores the menu router if we have it in memory.
  */
 function _menu_router_cache($new_menu = NULL) {
   $menu = &drupal_static(__FUNCTION__);
@@ -2757,7 +2769,7 @@ function _menu_router_cache($new_menu = NULL) {
 }
 
 /**
- * Get the menu router.
+ * Gets the menu router.
  */
 function menu_get_router() {
   // Check first if we have it in memory already.
@@ -2794,7 +2806,7 @@ function _menu_link_build($item) {
 }
 
 /**
- * Helper function to build menu links for the items in the menu router.
+ * Builds menu links for the items in the menu router.
  */
 function _menu_navigation_links_rebuild($menu) {
   // Add normal and suggested items as links.
@@ -2894,7 +2906,7 @@ function _menu_navigation_links_rebuild($menu) {
 }
 
 /**
- * Clone an array of menu links.
+ * Clones an array of menu links.
  *
  * @param $links
  *   An array of menu links to clone.
@@ -2985,12 +2997,14 @@ function menu_link_delete($mlid, $path = NULL) {
 }
 
 /**
- * Helper function for menu_link_delete; deletes a single menu link.
+ * Deletes a single menu link.
  *
  * @param $item
  *   Item to be deleted.
  * @param $force
  *   Forces deletion. Internal use only, setting to TRUE is discouraged.
+ *
+ * @see menu_link_delete()
  */
 function _menu_delete_item($item, $force = FALSE) {
   $item = is_object($item) ? get_object_vars($item) : $item;
@@ -3202,7 +3216,7 @@ function menu_link_save(&$item, $existing_item = array(), $parent_candidates = a
 }
 
 /**
- * Find a possible parent for a given menu link.
+ * Finds a possible parent for a given menu link.
  *
  * Because the parent of a given link might not exist anymore in the database,
  * we apply a set of heuristics to determine a proper parent:
@@ -3216,6 +3230,7 @@ function menu_link_save(&$item, $existing_item = array(), $parent_candidates = a
  *   A menu link.
  * @param $parent_candidates
  *   An array of menu links keyed by mlid.
+ *
  * @return
  *   A menu link structure of the possible parent or FALSE if no valid parent
  *   has been found.
@@ -3281,7 +3296,7 @@ function _menu_link_find_parent($menu_link, $parent_candidates = array()) {
 }
 
 /**
- * Helper function to clear the page and block caches at most twice per page load.
+ * Clears the page and block caches at most twice per page load.
  */
 function _menu_clear_page_cache() {
   $cache_cleared = &drupal_static(__FUNCTION__, 0);
@@ -3303,7 +3318,7 @@ function _menu_clear_page_cache() {
 }
 
 /**
- * Helper function to update a list of menus with expanded items
+ * Updates a list of menus with expanded items.
  */
 function _menu_set_expanded_menus() {
   $names = db_query("SELECT menu_name FROM {menu_links} WHERE expanded <> 0 GROUP BY menu_name")->fetchCol();
@@ -3311,7 +3326,7 @@ function _menu_set_expanded_menus() {
 }
 
 /**
- * Find the router path which will serve this path.
+ * Finds the router path which will serve this path.
  *
  * @param $link_path
  *  The path for we are looking up its router path.
@@ -3353,7 +3368,7 @@ function _menu_find_router_path($link_path) {
 }
 
 /**
- * Insert, update or delete an uncustomized menu link related to a module.
+ * Inserts, updates, or deletes an uncustomized menu link related to a module.
  *
  * @param $module
  *   The name of the module.
@@ -3393,7 +3408,7 @@ function menu_link_maintain($module, $op, $link_path, $link_title) {
 }
 
 /**
- * Find the depth of an item's children relative to its depth.
+ * Finds the depth of an item's children relative to its depth.
  *
  * For example, if the item has a depth of 2, and the maximum of any child in
  * the menu link tree is 5, the relative depth is 3.
@@ -3425,7 +3440,7 @@ function menu_link_children_relative_depth($item) {
 }
 
 /**
- * Update the children of a menu link that's being moved.
+ * Updates the children of a menu link that is being moved.
  *
  * The menu name, parents (p1 - p6), and depth are updated for all children of
  * the link, and the has_children status of the previous parent is updated.
@@ -3474,7 +3489,7 @@ function _menu_link_move_children($item, $existing_item) {
 }
 
 /**
- * Check and update the has_children status for the parent of a link.
+ * Checks and updates the 'has_children' status for the parent of a link.
  */
 function _menu_update_parental_status($item, $exclude = FALSE) {
   // If plid == 0, there is nothing to update.
@@ -3498,7 +3513,7 @@ function _menu_update_parental_status($item, $exclude = FALSE) {
 }
 
 /**
- * Helper function that sets the p1..p9 values for a menu link being saved.
+ * Sets the p1 through p9 values for a menu link being saved.
  */
 function _menu_link_parents_set(&$item, $parent) {
   $i = 1;
@@ -3516,7 +3531,7 @@ function _menu_link_parents_set(&$item, $parent) {
 }
 
 /**
- * Helper function to build the router table based on the data from hook_menu.
+ * Builds the router table based on the data from hook_menu().
  */
 function _menu_router_build($callbacks) {
   // First pass: separate callbacks from paths, making paths ready for
@@ -3743,7 +3758,7 @@ function _menu_router_build($callbacks) {
 }
 
 /**
- * Helper function to save data from menu_router_build() to the router table.
+ * Saves data from menu_router_build() to the router table.
  */
 function _menu_router_save($menu, $masks) {
   // Delete the existing router since we have some data to replace it.

+ 25 - 18
includes/module.inc

@@ -6,7 +6,7 @@
  */
 
 /**
- * Load all the modules that have been enabled in the system table.
+ * Loads all the modules that have been enabled in the system table.
  *
  * @param $bootstrap
  *   Whether to load only the reduced set of modules loaded in "bootstrap mode"
@@ -102,7 +102,7 @@ function module_list($refresh = FALSE, $bootstrap_refresh = FALSE, $sort = FALSE
 }
 
 /**
- * Build a list of bootstrap modules and enabled modules and themes.
+ * Builds a list of bootstrap modules and enabled modules and themes.
  *
  * @param $type
  *   The type of list to return:
@@ -181,6 +181,7 @@ function system_list($type) {
       foreach ($lists['theme'] as $key => $theme) {
         if (!empty($theme->info['base theme'])) {
           // Make a list of the theme's base themes.
+          require_once DRUPAL_ROOT . '/includes/theme.inc';
           $lists['theme'][$key]->base_themes = drupal_find_base_themes($lists['theme'], $key);
           // Don't proceed if there was a problem with the root base theme.
           if (!current($lists['theme'][$key]->base_themes)) {
@@ -218,7 +219,7 @@ function system_list($type) {
 }
 
 /**
- * Reset all system_list() caches.
+ * Resets all system_list() caches.
  */
 function system_list_reset() {
   drupal_static_reset('system_list');
@@ -229,7 +230,7 @@ function system_list_reset() {
 }
 
 /**
- * Find dependencies any level deep and fill in required by information too.
+ * Determines which modules require and are required by each module.
  *
  * @param $files
  *   The array of filesystem objects used to rebuild the cache.
@@ -262,7 +263,7 @@ function _module_build_dependencies($files) {
 }
 
 /**
- * Determine whether a given module exists.
+ * Determines whether a given module exists.
  *
  * @param $module
  *   The name of the module (without the .module extension).
@@ -276,7 +277,7 @@ function module_exists($module) {
 }
 
 /**
- * Load a module's installation hooks.
+ * Loads a module's installation hooks.
  *
  * @param $module
  *   The name of the module (without the .module extension).
@@ -292,7 +293,7 @@ function module_load_install($module) {
 }
 
 /**
- * Load a module include file.
+ * Loads a module include file.
  *
  * Examples:
  * @code
@@ -334,8 +335,7 @@ function module_load_include($type, $module, $name = NULL) {
 }
 
 /**
- * Load an include file for each of the modules that have been enabled in
- * the system table.
+ * Loads an include file for each module enabled in the {system} table.
  */
 function module_load_all_includes($type, $name = NULL) {
   $modules = module_list();
@@ -503,7 +503,7 @@ function module_enable($module_list, $enable_dependencies = TRUE) {
 }
 
 /**
- * Disable a given set of modules.
+ * Disables a given set of modules.
  *
  * @param $module_list
  *   An array of module names.
@@ -614,7 +614,7 @@ function module_disable($module_list, $disable_dependents = TRUE) {
  */
 
 /**
- * Determine whether a module implements a hook.
+ * Determines whether a module implements a hook.
  *
  * @param $module
  *   The name of the module (without the .module extension).
@@ -643,7 +643,7 @@ function module_hook($module, $hook) {
 }
 
 /**
- * Determine which modules are implementing a hook.
+ * Determines which modules are implementing a hook.
  *
  * @param $hook
  *   The name of the hook (e.g. "help" or "menu").
@@ -744,7 +744,14 @@ function module_implements($hook, $sort = FALSE, $reset = FALSE) {
 }
 
 /**
- * Retrieve a list of what hooks are explicitly declared.
+ * Retrieves a list of hooks that are declared through hook_hook_info().
+ *
+ * @return
+ *   An associative array whose keys are hook names and whose values are an
+ *   associative array containing a group name. The structure of the array
+ *   is the same as the return value of hook_hook_info().
+ *
+ * @see hook_hook_info()
  */
 function module_hook_info() {
   // This function is indirectly invoked from bootstrap_invoke_all(), in which
@@ -806,7 +813,7 @@ function module_implements_write_cache() {
 }
 
 /**
- * Invoke a hook in a particular module.
+ * Invokes a hook in a particular module.
  *
  * @param $module
  *   The name of the module (without the .module extension).
@@ -828,7 +835,7 @@ function module_invoke($module, $hook) {
 }
 
 /**
- * Invoke a hook in all enabled modules that implement it.
+ * Invokes a hook in all enabled modules that implement it.
  *
  * @param $hook
  *   The name of the hook to invoke.
@@ -865,13 +872,13 @@ function module_invoke_all($hook) {
  */
 
 /**
- * Array of modules required by core.
+ * Returns an array of modules required by core.
  */
 function drupal_required_modules() {
   $files = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info$/', 'modules', 'name', 0);
   $required = array();
 
-  // An install profile is required and one must always be loaded.
+  // An installation profile is required and one must always be loaded.
   $required[] = drupal_get_profile();
 
   foreach ($files as $name => $file) {
@@ -885,7 +892,7 @@ function drupal_required_modules() {
 }
 
 /**
- * Hands off alterable variables to type-specific *_alter implementations.
+ * Passes alterable variables to specific hook_TYPE_alter() implementations.
  *
  * This dispatch function hands off the passed-in variables to type-specific
  * hook_TYPE_alter() implementations in modules. It ensures a consistent

+ 19 - 1
includes/session.inc

@@ -349,6 +349,11 @@ function drupal_session_started($set = NULL) {
  */
 function drupal_session_regenerate() {
   global $user, $is_https;
+  // Nothing to do if we are not allowed to change the session.
+  if (!drupal_save_session()) {
+    return;
+  }
+
   if ($is_https && variable_get('https', FALSE)) {
     $insecure_session_name = substr(session_name(), 1);
     if (!isset($GLOBALS['lazy_session']) && isset($_COOKIE[$insecure_session_name])) {
@@ -418,6 +423,11 @@ function drupal_session_regenerate() {
 function _drupal_session_destroy($sid) {
   global $user, $is_https;
 
+  // Nothing to do if we are not allowed to change the session.
+  if (!drupal_save_session()) {
+    return;
+  }
+
   // Delete session data.
   db_delete('sessions')
     ->condition($is_https ? 'ssid' : 'sid', $sid)
@@ -465,6 +475,11 @@ function _drupal_session_delete_cookie($name, $secure = NULL) {
  *   User ID.
  */
 function drupal_session_destroy_uid($uid) {
+  // Nothing to do if we are not allowed to change the session.
+  if (!drupal_save_session()) {
+    return;
+  }
+
   db_delete('sessions')
     ->condition('uid', $uid)
     ->execute();
@@ -507,7 +522,10 @@ function _drupal_session_garbage_collection($lifetime) {
  *   FALSE if writing session data has been disabled. Otherwise, TRUE.
  */
 function drupal_save_session($status = NULL) {
-  $save_session = &drupal_static(__FUNCTION__, TRUE);
+  // PHP session ID, session, and cookie handling happens in the global scope.
+  // This value has to persist across calls to drupal_static_reset(), since a
+  // potentially wrong or disallowed session would be written otherwise.
+  static $save_session = TRUE;
   if (isset($status)) {
     $save_session = $status;
   }

+ 3 - 3
includes/stream_wrappers.inc

@@ -553,7 +553,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
    * Support for unlink().
    *
    * @param $uri
-   *   A string containing the uri to the resource to delete.
+   *   A string containing the URI to the resource to delete.
    *
    * @return
    *   TRUE if resource was successfully deleted.
@@ -569,9 +569,9 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
    * Support for rename().
    *
    * @param $from_uri,
-   *   The uri to the file to rename.
+   *   The URI to the file to rename.
    * @param $to_uri
-   *   The new uri for file.
+   *   The new URI for file.
    *
    * @return
    *   TRUE if file was successfully renamed.

+ 8 - 6
includes/theme.inc

@@ -2069,10 +2069,12 @@ function theme_item_list($variables) {
   if (!empty($items)) {
     $output .= "<$type" . drupal_attributes($attributes) . '>';
     $num_items = count($items);
-    foreach ($items as $i => $item) {
+    $i = 0;
+    foreach ($items as $item) {
       $attributes = array();
       $children = array();
       $data = '';
+      $i++;
       if (is_array($item)) {
         foreach ($item as $key => $value) {
           if ($key == 'data') {
@@ -2093,10 +2095,10 @@ function theme_item_list($variables) {
         // Render nested list.
         $data .= theme_item_list(array('items' => $children, 'title' => NULL, 'type' => $type, 'attributes' => $attributes));
       }
-      if ($i == 0) {
+      if ($i == 1) {
         $attributes['class'][] = 'first';
       }
-      if ($i == $num_items - 1) {
+      if ($i == $num_items) {
         $attributes['class'][] = 'last';
       }
       $output .= '<li' . drupal_attributes($attributes) . '>' . $data . "</li>\n";
@@ -2112,7 +2114,7 @@ function theme_item_list($variables) {
  *
  * @param $variables
  *   An associative array containing:
- *   - url: The url for the link.
+ *   - url: The URL for the link.
  */
 function theme_more_help_link($variables) {
   return '<div class="more-help-link">' . l(t('More help'), $variables['url']) . '</div>';
@@ -2128,7 +2130,7 @@ function theme_more_help_link($variables) {
  *   - title: A descriptive title of the feed.
  */
 function theme_feed_icon($variables) {
-  $text = t('Subscribe to @feed-title', array('@feed-title' => $variables['title']));
+  $text = t('Subscribe to !feed-title', array('!feed-title' => $variables['title']));
   if ($image = theme('image', array('path' => 'misc/feed.png', 'width' => 16, 'height' => 16, 'alt' => $text))) {
     return l($image, $variables['url'], array('html' => TRUE, 'attributes' => array('class' => array('feed-icon'), 'title' => $text)));
   }
@@ -2177,7 +2179,7 @@ function theme_html_tag($variables) {
  *
  * @param $variables
  *   An associative array containing:
- *   - url: The url of the main page.
+ *   - url: The URL of the main page.
  *   - title: A descriptive verb for the link, like 'Read more'.
  */
 function theme_more_link($variables) {

+ 2 - 2
includes/unicode.inc

@@ -96,7 +96,7 @@ function unicode_check() {
  *   Whether to report any fatal errors with form_set_error().
  */
 function _unicode_check() {
-  // Ensure translations don't break at install time
+  // Ensure translations don't break during installation.
   $t = get_t();
 
   // Check for mbstring extension
@@ -128,7 +128,7 @@ function _unicode_check() {
  * Return Unicode library status and errors.
  */
 function unicode_requirements() {
-  // Ensure translations don't break at install time
+  // Ensure translations don't break during installation.
   $t = get_t();
 
   $libraries = array(

+ 10 - 23
includes/update.inc

@@ -785,12 +785,12 @@ function update_fix_d7_requirements() {
 /**
  * Register the currently installed profile in the system table.
  *
- * Install profiles are now treated as modules by Drupal, and have an upgrade
- * path based on their schema version in the system table.
+ * Installation profiles are now treated as modules by Drupal, and have an
+ * upgrade path based on their schema version in the system table.
  *
- * The install profile will be set to schema_version 0, as it has already been
- * installed. Any other hook_update_N functions provided by the install profile
- * will be run by update.php.
+ * The installation profile will be set to schema_version 0, as it has already
+ * been installed. Any other hook_update_N functions provided by the
+ * installation profile will be run by update.php.
  */
 function update_fix_d7_install_profile() {
   $profile = drupal_get_profile();
@@ -828,10 +828,10 @@ function update_fix_d7_install_profile() {
       'owner' => '',
     );
 
-    // Install profile hooks are always executed last by the module system
+    // Installation profile hooks are always executed last by the module system
     $values['weight'] = 1000;
 
-    // Initializing the system table entry for the install profile
+    // Initializing the system table entry for the installation profile
     db_insert('system')
       ->fields(array_keys($values))
       ->values($values)
@@ -840,7 +840,8 @@ function update_fix_d7_install_profile() {
     // Reset the cached schema version.
     drupal_get_installed_schema_version($profile, TRUE);
 
-    // Load the updates again to make sure the install profile updates are loaded
+    // Load the updates again to make sure the installation profile updates
+    // are loaded.
     drupal_load_updates();
   }
 }
@@ -895,7 +896,7 @@ function update_get_d6_session_name() {
   }
   else {
     // Otherwise use $base_url as session name, without the protocol
-    // to use the same session identifiers across http and https.
+    // to use the same session identifiers across HTTP and HTTPS.
     list( , $session_name) = explode('://', $base_url, 2);
   }
 
@@ -1474,17 +1475,3 @@ function update_retrieve_dependencies() {
 
   return $return;
 }
-
-/**
- * @defgroup update-api-6.x-to-7.x Update versions of API functions
- * @{
- * Functions similar to normal API function but not firing hooks.
- *
- * During update, it is impossible to judge the consequences of firing a hook
- * as it might hit a module not yet updated. So simplified versions of some
- * core APIs are provided.
- */
-
-/**
- * @} End of "defgroup update-api-6.x-to-7.x".
- */

+ 2 - 3
misc/autocomplete.js

@@ -114,7 +114,6 @@ Drupal.jsAC.prototype.onkeyup = function (input, e) {
  */
 Drupal.jsAC.prototype.select = function (node) {
   this.input.value = $(node).data('autocompleteValue');
-  $(this.input).trigger('autocompleteSelect', [node]);
 };
 
 /**
@@ -168,7 +167,7 @@ Drupal.jsAC.prototype.unhighlight = function (node) {
 Drupal.jsAC.prototype.hidePopup = function (keycode) {
   // Select item if the right key or mousebutton was pressed.
   if (this.selected && ((keycode && keycode != 46 && keycode != 8 && keycode != 27) || !keycode)) {
-    this.select(this.selected);
+    this.input.value = $(this.selected).data('autocompleteValue');
   }
   // Hide popup.
   var popup = this.popup;
@@ -221,7 +220,7 @@ Drupal.jsAC.prototype.found = function (matches) {
   for (key in matches) {
     $('<li></li>')
       .html($('<div></div>').html(matches[key]))
-      .mousedown(function () { ac.hidePopup(this); })
+      .mousedown(function () { ac.select(this); })
       .mouseover(function () { ac.highlight(this); })
       .mouseout(function () { ac.unhighlight(this); })
       .data('autocompleteValue', key)

+ 1 - 1
misc/collapse.js

@@ -58,7 +58,7 @@ Drupal.behaviors.collapse = {
     $('fieldset.collapsible', context).once('collapse', function () {
       var $fieldset = $(this);
       // Expand fieldset if there are errors inside, or if it contains an
-      // element that is targeted by the uri fragment identifier. 
+      // element that is targeted by the URI fragment identifier. 
       var anchor = location.hash && location.hash != '#' ? ', ' + location.hash : '';
       if ($('.error' + anchor, $fieldset).length) {
         $fieldset.removeClass('collapsed');

+ 2 - 2
misc/states.js

@@ -482,8 +482,8 @@ $(document).bind('state:disabled', function(e) {
   if (e.trigger) {
     $(e.target)
       .attr('disabled', e.value)
-      .filter('.form-element')
-        .closest('.form-item, .form-submit, .form-wrapper').toggleClass('form-disabled', e.value);
+        .closest('.form-item, .form-submit, .form-wrapper').toggleClass('form-disabled', e.value)
+        .find('select, input, textarea').attr('disabled', e.value);
 
     // Note: WebKit nightlies don't reflect that change correctly.
     // See https://bugs.webkit.org/show_bug.cgi?id=23789

+ 1 - 1
modules/aggregator/aggregator.admin.inc

@@ -77,7 +77,7 @@ function aggregator_form_feed($form, &$form_state, stdClass $feed = NULL) {
   $form['url'] = array('#type' => 'textfield',
     '#title' => t('URL'),
     '#default_value' => isset($feed->url) ? $feed->url : '',
-    '#maxlength' => 255,
+    '#maxlength' => NULL,
     '#description' => t('The fully-qualified URL of the feed.'),
     '#required' => TRUE,
   );

+ 15 - 18
modules/aggregator/aggregator.api.php

@@ -19,8 +19,8 @@
  * parser; and finally, it is passed to all active processors, which manipulate
  * or store the data.
  *
- * Modules that define this hook can be set as active fetcher on
- * admin/config/services/aggregator. Only one fetcher can be active at a time.
+ * Modules that define this hook can be set as the active fetcher within the
+ * configuration page. Only one fetcher can be active at a time.
  *
  * @param $feed
  *   A feed object representing the resource to be downloaded. $feed->url
@@ -43,10 +43,9 @@ function hook_aggregator_fetch($feed) {
 /**
  * Specify the title and short description of your fetcher.
  *
- * The title and the description provided are shown on
- * admin/config/services/aggregator among other places. Use as title the human
- * readable name of the fetcher and as description a brief (40 to 80 characters)
- * explanation of the fetcher's functionality.
+ * The title and the description provided are shown within the configuration
+ * page. Use as title the human readable name of the fetcher and as description
+ * a brief (40 to 80 characters) explanation of the fetcher's functionality.
  *
  * This hook is only called if your module implements hook_aggregator_fetch().
  * If this hook is not implemented aggregator will use your module's file name
@@ -75,8 +74,8 @@ function hook_aggregator_fetch_info() {
  * active parser; and finally, it is passed to all active processors which
  * manipulate or store the data.
  *
- * Modules that define this hook can be set as the active parser on
- * admin/config/services/aggregator. Only one parser can be active at a time.
+ * Modules that define this hook can be set as the active parser within the
+ * configuration page. Only one parser can be active at a time.
  *
  * @param $feed
  *   An object describing the resource to be parsed. $feed->source_string
@@ -119,10 +118,9 @@ function hook_aggregator_parse($feed) {
 /**
  * Specify the title and short description of your parser.
  *
- * The title and the description provided are shown on
- * admin/config/services/aggregator among other places. Use as title the human
- * readable name of the parser and as description a brief (40 to 80 characters)
- * explanation of the parser's functionality.
+ * The title and the description provided are shown within the configuration
+ * page. Use as title the human readable name of the parser and as description
+ * a brief (40 to 80 characters) explanation of the parser's functionality.
  *
  * This hook is only called if your module implements hook_aggregator_parse().
  * If this hook is not implemented aggregator will use your module's file name
@@ -151,8 +149,8 @@ function hook_aggregator_parse_info() {
  * parser; and finally, it is passed to all active processors that manipulate or
  * store the data.
  *
- * Modules that define this hook can be activated as processor on
- * admin/config/services/aggregator.
+ * Modules that define this hook can be activated as a processor within the
+ * configuration page.
  *
  * @param $feed
  *   A feed object representing the resource to be processed. $feed->items
@@ -176,10 +174,9 @@ function hook_aggregator_process($feed) {
 /**
  * Specify the title and short description of your processor.
  *
- * The title and the description provided are shown most importantly on
- * admin/config/services/aggregator. Use as title the natural name of the
- * processor and as description a brief (40 to 80 characters) explanation of the
- * functionality.
+ * The title and the description provided are shown within the configuration
+ * page. Use as title the natural name of the processor and as description a
+ * brief (40 to 80 characters) explanation of the functionality.
  *
  * This hook is only called if your module implements hook_aggregator_process().
  * If this hook is not implemented aggregator will use your module's file name

+ 3 - 3
modules/aggregator/aggregator.info

@@ -7,8 +7,8 @@ files[] = aggregator.test
 configure = admin/config/services/aggregator/settings
 stylesheets[all][] = aggregator.css
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 38 - 16
modules/aggregator/aggregator.install

@@ -130,10 +130,8 @@ function aggregator_schema() {
         'description' => 'Title of the feed.',
       ),
       'url' => array(
-        'type' => 'varchar',
-        'length' => 255,
+        'type' => 'text',
         'not null' => TRUE,
-        'default' => '',
         'description' => 'URL to the feed.',
       ),
       'refresh' => array(
@@ -155,10 +153,8 @@ function aggregator_schema() {
         'description' => 'Time when this feed was queued for refresh, 0 if not queued.',
       ),
       'link' => array(
-        'type' => 'varchar',
-        'length' => 255,
+        'type' => 'text',
         'not null' => TRUE,
-        'default' => '',
         'description' => 'The parent website of the feed; comes from the <link> element in the feed.',
       ),
       'description' => array(
@@ -202,13 +198,13 @@ function aggregator_schema() {
       )
     ),
     'primary key' => array('fid'),
-    'unique keys' => array(
-      'url'  => array('url'),
-      'title' => array('title'),
-    ),
     'indexes' => array(
+      'url'  => array(array('url', 255)),
       'queued' => array('queued'),
     ),
+    'unique keys' => array(
+      'title' => array('title'),
+    ),
   );
 
   $schema['aggregator_item'] = array(
@@ -233,10 +229,8 @@ function aggregator_schema() {
         'description' => 'Title of the feed item.',
       ),
       'link' => array(
-        'type' => 'varchar',
-        'length' => 255,
+        'type' => 'text',
         'not null' => TRUE,
-        'default' => '',
         'description' => 'Link to the feed item.',
       ),
       'author' => array(
@@ -258,9 +252,8 @@ function aggregator_schema() {
         'description' => 'Posted date of the feed item, as a Unix timestamp.',
       ),
       'guid' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => FALSE,
+        'type' => 'text',
+        'not null' => TRUE,
         'description' => 'Unique identifier for the feed item.',
       )
     ),
@@ -279,6 +272,11 @@ function aggregator_schema() {
   return $schema;
 }
 
+/**
+ * @addtogroup updates-6.x-to-7.x
+ * @{
+ */
+
 /**
  * Add hash column to aggregator_feed table.
  */
@@ -306,3 +304,27 @@ function aggregator_update_7002() {
   db_add_index('aggregator_feed', 'queued', array('queued'));
 }
 
+/**
+ * @} End of "addtogroup updates-6.x-to-7.x"
+ */
+
+/**
+ * @addtogroup updates-7.x-extra
+ * @{
+ */
+
+/**
+ * Increase the length of {aggregator_feed}.url.
+ */
+function aggregator_update_7003() {
+  db_drop_unique_key('aggregator_feed', 'url');
+  db_change_field('aggregator_feed', 'url', 'url', array('type' => 'text', 'not null' => TRUE, 'description' => 'URL to the feed.'));
+  db_change_field('aggregator_feed', 'link', 'link', array('type' => 'text', 'not null' => TRUE, 'description' => 'The parent website of the feed; comes from the <link> element in the feed.'));
+  db_change_field('aggregator_item', 'link', 'link', array('type' => 'text', 'not null' => TRUE, 'description' => 'Link to the feed item.'));
+  db_change_field('aggregator_item', 'guid', 'guid', array('type' => 'text', 'not null' => TRUE, 'description' => 'Unique identifier for the feed item.'));
+  db_add_index('aggregator_feed', 'url', array(array('url', 255)));
+}
+
+/**
+ * @} End of "addtogroup updates-7.x-extra"
+ */

+ 3 - 4
modules/aggregator/aggregator.module

@@ -534,6 +534,7 @@ function aggregator_save_feed($edit) {
         'url' => $edit['url'],
         'refresh' => $edit['refresh'],
         'block' => $edit['block'],
+        'link' => '',
         'description' => '',
         'image' => '',
       ))
@@ -568,15 +569,13 @@ function aggregator_remove($feed) {
   // Call hook_aggregator_remove() on all modules.
   module_invoke_all('aggregator_remove', $feed);
   // Reset feed.
-  db_merge('aggregator_feed')
-    ->key(array('fid' => $feed->fid))
+  db_update('aggregator_feed')
+    ->condition('fid', $feed->fid)
     ->fields(array(
       'checked' => 0,
       'hash' => '',
       'etag' => '',
       'modified' => 0,
-      'description' => $feed->description,
-      'image' => $feed->image,
     ))
     ->execute();
 }

+ 2 - 1
modules/aggregator/aggregator.processor.inc

@@ -38,8 +38,9 @@ function aggregator_aggregator_process($feed) {
           $item['timestamp'] = isset($entry->timestamp) ? $entry->timestamp : REQUEST_TIME;
         }
 
-        // Make sure the item title fits in 255 varchar column.
+        // Make sure the item title and author fit in the 255 varchar column.
         $item['title'] = truncate_utf8($item['title'], 255, TRUE, TRUE);
+        $item['author'] = truncate_utf8($item['author'], 255, TRUE, TRUE);
         aggregator_save_item(array('iid' => (isset($entry->iid) ? $entry->iid : ''), 'fid' => $feed->fid, 'timestamp' => $item['timestamp'], 'title' => $item['title'], 'link' => $item['link'], 'author' => $item['author'], 'description' => $item['description'], 'guid' => $item['guid']));
       }
     }

+ 98 - 60
modules/aggregator/aggregator.test

@@ -25,10 +25,10 @@ class AggregatorTestCase extends DrupalWebTestCase {
   function createFeed($feed_url = NULL) {
     $edit = $this->getFeedEditArray($feed_url);
     $this->drupalPost('admin/config/services/aggregator/add/feed', $edit, t('Save'));
-    $this->assertRaw(t('The feed %name has been added.', array('%name' => $edit['title'])), t('The feed !name has been added.', array('!name' => $edit['title'])));
+    $this->assertRaw(t('The feed %name has been added.', array('%name' => $edit['title'])), format_string('The feed !name has been added.', array('!name' => $edit['title'])));
 
     $feed = db_query("SELECT *  FROM {aggregator_feed} WHERE title = :title AND url = :url", array(':title' => $edit['title'], ':url' => $edit['url']))->fetch();
-    $this->assertTrue(!empty($feed), t('The feed found in database.'));
+    $this->assertTrue(!empty($feed), 'The feed found in database.');
     return $feed;
   }
 
@@ -40,7 +40,7 @@ class AggregatorTestCase extends DrupalWebTestCase {
    */
   function deleteFeed($feed) {
     $this->drupalPost('admin/config/services/aggregator/edit/feed/' . $feed->fid, array(), t('Delete'));
-    $this->assertRaw(t('The feed %title has been deleted.', array('%title' => $feed->title)), t('Feed deleted successfully.'));
+    $this->assertRaw(t('The feed %title has been deleted.', array('%title' => $feed->title)), 'Feed deleted successfully.');
   }
 
   /**
@@ -90,7 +90,7 @@ class AggregatorTestCase extends DrupalWebTestCase {
   function updateFeedItems(&$feed, $expected_count) {
     // First, let's ensure we can get to the rss xml.
     $this->drupalGet($feed->url);
-    $this->assertResponse(200, t('!url is reachable.', array('!url' => $feed->url)));
+    $this->assertResponse(200, format_string('!url is reachable.', array('!url' => $feed->url)));
 
     // Attempt to access the update link directly without an access token.
     $this->drupalGet('admin/config/services/aggregator/update/' . $feed->fid);
@@ -108,7 +108,7 @@ class AggregatorTestCase extends DrupalWebTestCase {
       $feed->items[] = $item->iid;
     }
     $feed->item_count = count($feed->items);
-    $this->assertEqual($expected_count, $feed->item_count, t('Total items in feed equal to the total items in database (!val1 != !val2)', array('!val1' => $expected_count, '!val2' => $feed->item_count)));
+    $this->assertEqual($expected_count, $feed->item_count, format_string('Total items in feed equal to the total items in database (!val1 != !val2)', array('!val1' => $expected_count, '!val2' => $feed->item_count)));
   }
 
   /**
@@ -119,7 +119,7 @@ class AggregatorTestCase extends DrupalWebTestCase {
    */
   function removeFeedItems($feed) {
     $this->drupalPost('admin/config/services/aggregator/remove/' . $feed->fid, array(), t('Remove items'));
-    $this->assertRaw(t('The news items from %title have been removed.', array('%title' => $feed->title)), t('Feed items removed.'));
+    $this->assertRaw(t('The news items from %title have been removed.', array('%title' => $feed->title)), 'Feed items removed.');
   }
 
   /**
@@ -167,12 +167,12 @@ class AggregatorTestCase extends DrupalWebTestCase {
 
 
   /**
-   * Check if the feed name and url is unique.
+   * Check if the feed name and URL is unique.
    *
    * @param $feed_name
    *   String containing the feed name to check.
    * @param $feed_url
-   *   String containing the feed url to check.
+   *   String containing the feed URL to check.
    * @return
    *   TRUE if feed is unique.
    */
@@ -316,7 +316,7 @@ class AggregatorConfigurationTestCase extends AggregatorTestCase {
     $this->assertText(t('The configuration options have been saved.'));
 
     foreach ($edit as $name => $value) {
-      $this->assertFieldByName($name, $value, t('"@name" has correct default value.', array('@name' => $name)));
+      $this->assertFieldByName($name, $value, format_string('"@name" has correct default value.', array('@name' => $name)));
     }
   }
 }
@@ -337,19 +337,48 @@ class AddFeedTestCase extends AggregatorTestCase {
     $feed = $this->createFeed();
 
     // Check feed data.
-    $this->assertEqual($this->getUrl(), url('admin/config/services/aggregator/add/feed', array('absolute' => TRUE)), t('Directed to correct url.'));
-    $this->assertTrue($this->uniqueFeed($feed->title, $feed->url), t('The feed is unique.'));
+    $this->assertEqual($this->getUrl(), url('admin/config/services/aggregator/add/feed', array('absolute' => TRUE)), 'Directed to correct url.');
+    $this->assertTrue($this->uniqueFeed($feed->title, $feed->url), 'The feed is unique.');
 
     // Check feed source.
     $this->drupalGet('aggregator/sources/' . $feed->fid);
-    $this->assertResponse(200, t('Feed source exists.'));
-    $this->assertText($feed->title, t('Page title'));
+    $this->assertResponse(200, 'Feed source exists.');
+    $this->assertText($feed->title, 'Page title');
     $this->drupalGet('aggregator/sources/' . $feed->fid . '/categorize');
-    $this->assertResponse(200, t('Feed categorization page exists.'));
+    $this->assertResponse(200, 'Feed categorization page exists.');
 
     // Delete feed.
     $this->deleteFeed($feed);
   }
+
+  /**
+   * Tests feeds with very long URLs.
+   */
+  function testAddLongFeed() {
+    // Create a feed with a URL of > 255 characters.
+    $long_url = "https://www.google.com/search?ix=heb&sourceid=chrome&ie=UTF-8&q=angie+byron#sclient=psy-ab&hl=en&safe=off&source=hp&q=angie+byron&pbx=1&oq=angie+byron&aq=f&aqi=&aql=&gs_sm=3&gs_upl=0l0l0l10534l0l0l0l0l0l0l0l0ll0l0&bav=on.2,or.r_gc.r_pw.r_cp.,cf.osb&fp=a70b6b1f0abe28d8&biw=1629&bih=889&ix=heb";
+    $feed = $this->createFeed($long_url);
+
+    // Create a second feed of > 255 characters, where the only difference is
+    // after the 255th character.
+    $long_url_2 = "https://www.google.com/search?ix=heb&sourceid=chrome&ie=UTF-8&q=angie+byron#sclient=psy-ab&hl=en&safe=off&source=hp&q=angie+byron&pbx=1&oq=angie+byron&aq=f&aqi=&aql=&gs_sm=3&gs_upl=0l0l0l10534l0l0l0l0l0l0l0l0ll0l0&bav=on.2,or.r_gc.r_pw.r_cp.,cf.osb&fp=a70b6b1f0abe28d8&biw=1629&bih=889";
+    $feed_2 = $this->createFeed($long_url_2);
+
+    // Check feed data.
+    $this->assertTrue($this->uniqueFeed($feed->title, $feed->url), 'The first long URL feed is unique.');
+    $this->assertTrue($this->uniqueFeed($feed_2->title, $feed_2->url), 'The second long URL feed is unique.');
+
+    // Check feed source.
+    $this->drupalGet('aggregator/sources/' . $feed->fid);
+    $this->assertResponse(200, 'Long URL feed source exists.');
+    $this->assertText($feed->title, 'Page title');
+    $this->drupalGet('aggregator/sources/' . $feed->fid . '/categorize');
+    $this->assertResponse(200, 'Long URL feed categorization page exists.');
+
+    // Delete feeds.
+    $this->deleteFeed($feed);
+    $this->deleteFeed($feed_2);
+  }
 }
 
 class CategorizeFeedTestCase extends AggregatorTestCase {
@@ -369,11 +398,11 @@ class CategorizeFeedTestCase extends AggregatorTestCase {
     // Create 2 categories.
     $category_1 = array('title' => $this->randomName(10), 'description' => '');
     $this->drupalPost('admin/config/services/aggregator/add/category', $category_1, t('Save'));
-    $this->assertRaw(t('The category %title has been added.', array('%title' => $category_1['title'])), t('The category %title has been added.', array('%title' => $category_1['title'])));
+    $this->assertRaw(t('The category %title has been added.', array('%title' => $category_1['title'])), format_string('The category %title has been added.', array('%title' => $category_1['title'])));
 
     $category_2 = array('title' => $this->randomName(10), 'description' => '');
     $this->drupalPost('admin/config/services/aggregator/add/category', $category_2, t('Save'));
-    $this->assertRaw(t('The category %title has been added.', array('%title' => $category_2['title'])), t('The category %title has been added.', array('%title' => $category_2['title'])));
+    $this->assertRaw(t('The category %title has been added.', array('%title' => $category_2['title'])), format_string('The category %title has been added.', array('%title' => $category_2['title'])));
 
     // Get categories from database.
     $categories = $this->getCategories();
@@ -391,7 +420,7 @@ class CategorizeFeedTestCase extends AggregatorTestCase {
 
     // Assert the feed has two categories.
     $this->getFeedCategories($db_feed);
-    $this->assertEqual(count($db_feed->categories), 2, t('Feed has 2 categories'));
+    $this->assertEqual(count($db_feed->categories), 2, 'Feed has 2 categories');
   }
 }
 
@@ -419,16 +448,16 @@ class UpdateFeedTestCase extends AggregatorTestCase {
         $edit[$same_field] = $feed->{$same_field};
       }
       $this->drupalPost('admin/config/services/aggregator/edit/feed/' . $feed->fid, $edit, t('Save'));
-      $this->assertRaw(t('The feed %name has been updated.', array('%name' => $edit['title'])), t('The feed %name has been updated.', array('%name' => $edit['title'])));
+      $this->assertRaw(t('The feed %name has been updated.', array('%name' => $edit['title'])), format_string('The feed %name has been updated.', array('%name' => $edit['title'])));
 
       // Check feed data.
       $this->assertEqual($this->getUrl(), url('admin/config/services/aggregator/', array('absolute' => TRUE)));
-      $this->assertTrue($this->uniqueFeed($edit['title'], $edit['url']), t('The feed is unique.'));
+      $this->assertTrue($this->uniqueFeed($edit['title'], $edit['url']), 'The feed is unique.');
 
       // Check feed source.
       $this->drupalGet('aggregator/sources/' . $feed->fid);
-      $this->assertResponse(200, t('Feed source exists.'));
-      $this->assertText($edit['title'], t('Page title'));
+      $this->assertResponse(200, 'Feed source exists.');
+      $this->assertText($edit['title'], 'Page title');
 
       // Delete feed.
       $feed->title = $edit['title']; // Set correct title so deleteFeed() will work.
@@ -457,11 +486,11 @@ class RemoveFeedTestCase extends AggregatorTestCase {
 
     // Check feed source.
     $this->drupalGet('aggregator/sources/' . $feed->fid);
-    $this->assertResponse(404, t('Deleted feed source does not exists.'));
+    $this->assertResponse(404, 'Deleted feed source does not exists.');
 
     // Check database for feed.
     $result = db_query("SELECT COUNT(*) FROM {aggregator_feed} WHERE title = :title AND url = :url", array(':title' => $feed->title, ':url' => $feed->url))->fetchField();
-    $this->assertFalse($result, t('Feed not found in database'));
+    $this->assertFalse($result, 'Feed not found in database');
   }
 }
 
@@ -497,10 +526,10 @@ class UpdateFeedItemTestCase extends AggregatorTestCase {
     );
 
     $this->drupalGet($edit['url']);
-    $this->assertResponse(array(200), t('URL !url is accessible', array('!url' => $edit['url'])));
+    $this->assertResponse(array(200), format_string('URL !url is accessible', array('!url' => $edit['url'])));
 
     $this->drupalPost('admin/config/services/aggregator/add/feed', $edit, t('Save'));
-    $this->assertRaw(t('The feed %name has been added.', array('%name' => $edit['title'])), t('The feed !name has been added.', array('!name' => $edit['title'])));
+    $this->assertRaw(t('The feed %name has been added.', array('%name' => $edit['title'])), format_string('The feed !name has been added.', array('!name' => $edit['title'])));
 
     $feed = db_query("SELECT * FROM {aggregator_feed} WHERE url = :url", array(':url' => $edit['url']))->fetchObject();
 
@@ -521,7 +550,7 @@ class UpdateFeedItemTestCase extends AggregatorTestCase {
     aggregator_refresh($feed);
 
     $after = db_query('SELECT timestamp FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField();
-    $this->assertTrue($before === $after, t('Publish timestamp of feed item was not updated (!before === !after)', array('!before' => $before, '!after' => $after)));
+    $this->assertTrue($before === $after, format_string('Publish timestamp of feed item was not updated (!before === !after)', array('!before' => $before, '!after' => $after)));
   }
 }
 
@@ -554,9 +583,9 @@ class RemoveFeedItemTestCase extends AggregatorTestCase {
       // Update and remove items two times in a row to make sure that removal
       // resets all 'modified' information (modified, etag, hash) and allows for
       // immediate update.
-      $this->updateAndRemove($feed, 2);
-      $this->updateAndRemove($feed, 2);
-      $this->updateAndRemove($feed, 2);
+      $this->updateAndRemove($feed, 4);
+      $this->updateAndRemove($feed, 4);
+      $this->updateAndRemove($feed, 4);
       // Delete feed.
       $this->deleteFeed($feed);
     }
@@ -582,14 +611,14 @@ class CategorizeFeedItemTestCase extends AggregatorTestCase {
     // Simulate form submission on "admin/config/services/aggregator/add/category".
     $edit = array('title' => $this->randomName(10), 'description' => '');
     $this->drupalPost('admin/config/services/aggregator/add/category', $edit, t('Save'));
-    $this->assertRaw(t('The category %title has been added.', array('%title' => $edit['title'])), t('The category %title has been added.', array('%title' => $edit['title'])));
+    $this->assertRaw(t('The category %title has been added.', array('%title' => $edit['title'])), format_string('The category %title has been added.', array('%title' => $edit['title'])));
 
     $category = db_query("SELECT * FROM {aggregator_category} WHERE title = :title", array(':title' => $edit['title']))->fetch();
-    $this->assertTrue(!empty($category), t('The category found in database.'));
+    $this->assertTrue(!empty($category), 'The category found in database.');
 
     $link_path = 'aggregator/categories/' . $category->cid;
     $menu_link = db_query("SELECT * FROM {menu_links} WHERE link_path = :link_path", array(':link_path' => $link_path))->fetch();
-    $this->assertTrue(!empty($menu_link), t('The menu link associated with the category found in database.'));
+    $this->assertTrue(!empty($menu_link), 'The menu link associated with the category found in database.');
 
     $feed = $this->createFeed();
     db_insert('aggregator_category_feed')
@@ -600,7 +629,7 @@ class CategorizeFeedItemTestCase extends AggregatorTestCase {
       ->execute();
     $this->updateFeedItems($feed, $this->getDefaultFeedItemCount());
     $this->getFeedCategories($feed);
-    $this->assertTrue(!empty($feed->categories), t('The category found in the feed.'));
+    $this->assertTrue(!empty($feed->categories), 'The category found in the feed.');
 
     // For each category of a feed, ensure feed items have that category, too.
     if (!empty($feed->categories) && !empty($feed->items)) {
@@ -611,7 +640,7 @@ class CategorizeFeedItemTestCase extends AggregatorTestCase {
           ->execute()
           ->fetchField();
 
-        $this->assertEqual($feed->item_count, $categorized_count, t('Total items in feed equal to the total categorized feed items in database'));
+        $this->assertEqual($feed->item_count, $categorized_count, 'Total items in feed equal to the total categorized feed items in database');
       }
     }
 
@@ -644,11 +673,11 @@ class ImportOPMLTestCase extends AggregatorTestCase {
       ->execute();
 
     $this->drupalGet('admin/config/services/aggregator/add/opml');
-    $this->assertText('A single OPML document may contain a collection of many feeds.', t('Found OPML help text.'));
-    $this->assertField('files[upload]', t('Found file upload field.'));
-    $this->assertField('remote', t('Found Remote URL field.'));
-    $this->assertField('refresh', '', t('Found Refresh field.'));
-    $this->assertFieldByName("category[$cid]", $cid, t('Found category field.'));
+    $this->assertText('A single OPML document may contain a collection of many feeds.', 'Found OPML help text.');
+    $this->assertField('files[upload]', 'Found file upload field.');
+    $this->assertField('remote', 'Found Remote URL field.');
+    $this->assertField('refresh', 'Found Refresh field.');
+    $this->assertFieldByName("category[$cid]", $cid, 'Found category field.');
   }
 
   /**
@@ -659,7 +688,7 @@ class ImportOPMLTestCase extends AggregatorTestCase {
 
     $edit = array();
     $this->drupalPost('admin/config/services/aggregator/add/opml', $edit, t('Import'));
-    $this->assertRaw(t('You must <em>either</em> upload a file or enter a URL.'), t('Error if no fields are filled.'));
+    $this->assertRaw(t('You must <em>either</em> upload a file or enter a URL.'), 'Error if no fields are filled.');
 
     $path = $this->getEmptyOpml();
     $edit = array(
@@ -667,14 +696,14 @@ class ImportOPMLTestCase extends AggregatorTestCase {
       'remote' => file_create_url($path),
     );
     $this->drupalPost('admin/config/services/aggregator/add/opml', $edit, t('Import'));
-    $this->assertRaw(t('You must <em>either</em> upload a file or enter a URL.'), t('Error if both fields are filled.'));
+    $this->assertRaw(t('You must <em>either</em> upload a file or enter a URL.'), 'Error if both fields are filled.');
 
     $edit = array('remote' => 'invalidUrl://empty');
     $this->drupalPost('admin/config/services/aggregator/add/opml', $edit, t('Import'));
-    $this->assertText(t('This URL is not valid.'), t('Error if the URL is invalid.'));
+    $this->assertText(t('This URL is not valid.'), 'Error if the URL is invalid.');
 
     $after = db_query('SELECT COUNT(*) FROM {aggregator_feed}')->fetchField();
-    $this->assertEqual($before, $after, t('No feeds were added during the three last form submissions.'));
+    $this->assertEqual($before, $after, 'No feeds were added during the three last form submissions.');
   }
 
   /**
@@ -685,14 +714,14 @@ class ImportOPMLTestCase extends AggregatorTestCase {
 
     $form['files[upload]'] = $this->getInvalidOpml();
     $this->drupalPost('admin/config/services/aggregator/add/opml', $form, t('Import'));
-    $this->assertText(t('No new feed has been added.'), t('Attempting to upload invalid XML.'));
+    $this->assertText(t('No new feed has been added.'), 'Attempting to upload invalid XML.');
 
     $edit = array('remote' => file_create_url($this->getEmptyOpml()));
     $this->drupalPost('admin/config/services/aggregator/add/opml', $edit, t('Import'));
-    $this->assertText(t('No new feed has been added.'), t('Attempting to load empty OPML from remote URL.'));
+    $this->assertText(t('No new feed has been added.'), 'Attempting to load empty OPML from remote URL.');
 
     $after = db_query('SELECT COUNT(*) FROM {aggregator_feed}')->fetchField();
-    $this->assertEqual($before, $after, t('No feeds were added during the two last form submissions.'));
+    $this->assertEqual($before, $after, 'No feeds were added during the two last form submissions.');
 
     db_delete('aggregator_feed')->execute();
     db_delete('aggregator_category')->execute();
@@ -716,11 +745,11 @@ class ImportOPMLTestCase extends AggregatorTestCase {
       'category[1]'   => $category,
     );
     $this->drupalPost('admin/config/services/aggregator/add/opml', $edit, t('Import'));
-    $this->assertRaw(t('A feed with the URL %url already exists.', array('%url' => $feeds[0]['url'])), t('Verifying that a duplicate URL was identified'));
-    $this->assertRaw(t('A feed named %title already exists.', array('%title' => $feeds[1]['title'])), t('Verifying that a duplicate title was identified'));
+    $this->assertRaw(t('A feed with the URL %url already exists.', array('%url' => $feeds[0]['url'])), 'Verifying that a duplicate URL was identified');
+    $this->assertRaw(t('A feed named %title already exists.', array('%title' => $feeds[1]['title'])), 'Verifying that a duplicate title was identified');
 
     $after = db_query('SELECT COUNT(*) FROM {aggregator_feed}')->fetchField();
-    $this->assertEqual($after, 2, t('Verifying that two distinct feeds were added.'));
+    $this->assertEqual($after, 2, 'Verifying that two distinct feeds were added.');
 
     $feeds_from_db = db_query("SELECT f.title, f.url, f.refresh, cf.cid FROM {aggregator_feed} f LEFT JOIN {aggregator_category_feed} cf ON f.fid = cf.fid");
     $refresh = $category = TRUE;
@@ -731,10 +760,10 @@ class ImportOPMLTestCase extends AggregatorTestCase {
       $refresh = $refresh && $feed->refresh == 900;
     }
 
-    $this->assertEqual($title[$feeds[0]['url']], $feeds[0]['title'], t('First feed was added correctly.'));
-    $this->assertEqual($url[$feeds[1]['title']], $feeds[1]['url'], t('Second feed was added correctly.'));
-    $this->assertTrue($refresh, t('Refresh times are correct.'));
-    $this->assertTrue($category, t('Categories are correct.'));
+    $this->assertEqual($title[$feeds[0]['url']], $feeds[0]['title'], 'First feed was added correctly.');
+    $this->assertEqual($url[$feeds[1]['title']], $feeds[1]['url'], 'Second feed was added correctly.');
+    $this->assertTrue($refresh, 'Refresh times are correct.');
+    $this->assertTrue($category, 'Categories are correct.');
   }
 
   function testOPMLImport() {
@@ -834,20 +863,20 @@ class AggregatorRenderingTestCase extends AggregatorTestCase {
     $this->assertFieldByName('blocks[' . $block['module'] . '_' . $block['delta'] . '][region]', '', 'Aggregator feed block is available for positioning.');
     // Position it.
     $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
-    $this->assertText(t('The block settings have been updated.'), t('Block successfully moved to %region_name region.', array( '%region_name' => $region)));
+    $this->assertText(t('The block settings have been updated.'), format_string('Block successfully moved to %region_name region.', array( '%region_name' => $region)));
     // Confirm that the block is now being displayed on pages.
     $this->drupalGet('node');
-    $this->assertText(t($block['title']), t('Feed block is displayed on the page.'));
+    $this->assertText(t($block['title']), 'Feed block is displayed on the page.');
 
     // Find the expected read_more link.
     $href = 'aggregator/sources/' . $feed->fid;
     $links = $this->xpath('//a[@href = :href]', array(':href' => url($href)));
-    $this->assert(isset($links[0]), t('Link to href %href found.', array('%href' => $href)));
+    $this->assert(isset($links[0]), format_string('Link to href %href found.', array('%href' => $href)));
 
     // Visit that page.
     $this->drupalGet($href);
     $correct_titles = $this->xpath('//h1[normalize-space(text())=:title]', array(':title' => $feed->title));
-    $this->assertFalse(empty($correct_titles), t('Aggregator feed page is available and has the correct title.'));
+    $this->assertFalse(empty($correct_titles), 'Aggregator feed page is available and has the correct title.');
 
     // Set the number of news items to 0 to test that the block does not show
     // up.
@@ -876,7 +905,7 @@ class AggregatorRenderingTestCase extends AggregatorTestCase {
     // Check for the presence of a pager.
     $this->drupalGet('aggregator/sources/' . $feed->fid);
     $elements = $this->xpath("//ul[@class=:class]", array(':class' => 'pager'));
-    $this->assertTrue(!empty($elements), t('Individual source page contains a pager.'));
+    $this->assertTrue(!empty($elements), 'Individual source page contains a pager.');
 
     // Reset the number of items in rss.xml to the default value.
     variable_set('feed_default_items', 10);
@@ -910,10 +939,19 @@ class FeedParserTestCase extends AggregatorTestCase {
     $feed = $this->createFeed($this->getRSS091Sample());
     aggregator_refresh($feed);
     $this->drupalGet('aggregator/sources/' . $feed->fid);
-    $this->assertResponse(200, t('Feed %name exists.', array('%name' => $feed->title)));
+    $this->assertResponse(200, format_string('Feed %name exists.', array('%name' => $feed->title)));
     $this->assertText('First example feed item title');
     $this->assertLinkByHref('http://example.com/example-turns-one');
     $this->assertText('First example feed item description.');
+
+    // Several additional items that include elements over 255 characters.
+    $this->assertRaw("Second example feed item title.");
+    $this->assertText('Long link feed item title');
+    $this->assertText('Long link feed item description');
+    $this->assertLinkByHref('http://example.com/tomorrow/and/tomorrow/and/tomorrow/creeps/in/this/petty/pace/from/day/to/day/to/the/last/syllable/of/recorded/time/and/all/our/yesterdays/have/lighted/fools/the/way/to/dusty/death/out/out/brief/candle/life/is/but/a/walking/shadow/a/poor/player/that/struts/and/frets/his/hour/upon/the/stage/and/is/heard/no/more/it/is/a/tale/told/by/an/idiot/full/of/sound/and/fury/signifying/nothing');
+    $this->assertText('Long author feed item title');
+    $this->assertText('Long author feed item description');
+    $this->assertLinkByHref('http://example.com/long/author');
   }
 
   /**
@@ -923,7 +961,7 @@ class FeedParserTestCase extends AggregatorTestCase {
     $feed = $this->createFeed($this->getAtomSample());
     aggregator_refresh($feed);
     $this->drupalGet('aggregator/sources/' . $feed->fid);
-    $this->assertResponse(200, t('Feed %name exists.', array('%name' => $feed->title)));
+    $this->assertResponse(200, format_string('Feed %name exists.', array('%name' => $feed->title)));
     $this->assertText('Atom-Powered Robots Run Amok');
     $this->assertLinkByHref('http://example.org/2003/12/13/atom03');
     $this->assertText('Some text.');

+ 3 - 3
modules/aggregator/tests/aggregator_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

File diff suppressed because it is too large
+ 8 - 0
modules/aggregator/tests/aggregator_test_rss091.xml


+ 1 - 0
modules/block/block.api.php

@@ -55,6 +55,7 @@
  *       viewed.
  *     - DRUPAL_CACHE_GLOBAL: The block is the same for every user on every page
  *       where it is visible.
+ *     - DRUPAL_CACHE_CUSTOM: The module implements its own caching system.
  *     - DRUPAL_NO_CACHE: The block should not get cached.
  *   - properties: (optional) Array of additional metadata to add to the block.
  *     Common properties include:

+ 3 - 3
modules/block/block.info

@@ -6,8 +6,8 @@ core = 7.x
 files[] = block.test
 configure = admin/structure/block
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 65 - 65
modules/block/block.test

@@ -45,9 +45,9 @@ class BlockTestCase extends DrupalWebTestCase {
   function testCustomBlock() {
     // Confirm that the add block link appears on block overview pages.
     $this->drupalGet('admin/structure/block');
-    $this->assertRaw(l('Add block', 'admin/structure/block/add'), t('Add block link is present on block overview page for default theme.'));
+    $this->assertRaw(l('Add block', 'admin/structure/block/add'), 'Add block link is present on block overview page for default theme.');
     $this->drupalGet('admin/structure/block/list/seven');
-    $this->assertRaw(l('Add block', 'admin/structure/block/list/seven/add'), t('Add block link is present on block overview page for non-default theme.'));
+    $this->assertRaw(l('Add block', 'admin/structure/block/list/seven/add'), 'Add block link is present on block overview page for non-default theme.');
 
     // Confirm that hidden regions are not shown as options for block placement
     // when adding a new block.
@@ -58,7 +58,7 @@ class BlockTestCase extends DrupalWebTestCase {
       if ($theme->status) {
         foreach ($theme->info['regions_hidden'] as $hidden_region) {
           $elements = $this->xpath('//select[@id=:id]//option[@value=:value]', array(':id' => 'edit-regions-' . $key, ':value' => $hidden_region));
-          $this->assertFalse(isset($elements[0]), t('The hidden region @region is not available for @theme.', array('@region' => $hidden_region, '@theme' => $key)));
+          $this->assertFalse(isset($elements[0]), format_string('The hidden region @region is not available for @theme.', array('@region' => $hidden_region, '@theme' => $key)));
         }
       }
     }
@@ -71,17 +71,17 @@ class BlockTestCase extends DrupalWebTestCase {
     $this->drupalPost('admin/structure/block/add', $custom_block, t('Save block'));
 
     // Confirm that the custom block has been created, and then query the created bid.
-    $this->assertText(t('The block has been created.'), t('Custom block successfully created.'));
+    $this->assertText(t('The block has been created.'), 'Custom block successfully created.');
     $bid = db_query("SELECT bid FROM {block_custom} WHERE info = :info", array(':info' => $custom_block['info']))->fetchField();
 
     // Check to see if the custom block was created by checking that it's in the database.
-    $this->assertNotNull($bid, t('Custom block found in database'));
+    $this->assertNotNull($bid, 'Custom block found in database');
 
     // Check that block_block_view() returns the correct title and content.
     $data = block_block_view($bid);
     $format = db_query("SELECT format FROM {block_custom} WHERE bid = :bid", array(':bid' => $bid))->fetchField();
-    $this->assertTrue(array_key_exists('subject', $data) && empty($data['subject']), t('block_block_view() provides an empty block subject, since custom blocks do not have default titles.'));
-    $this->assertEqual(check_markup($custom_block['body[value]'], $format), $data['content'], t('block_block_view() provides correct block content.'));
+    $this->assertTrue(array_key_exists('subject', $data) && empty($data['subject']), 'block_block_view() provides an empty block subject, since custom blocks do not have default titles.');
+    $this->assertEqual(check_markup($custom_block['body[value]'], $format), $data['content'], 'block_block_view() provides correct block content.');
 
     // Check whether the block can be moved to all available regions.
     $custom_block['module'] = 'block';
@@ -92,8 +92,8 @@ class BlockTestCase extends DrupalWebTestCase {
 
     // Verify presence of configure and delete links for custom block.
     $this->drupalGet('admin/structure/block');
-    $this->assertLinkByHref('admin/structure/block/manage/block/' . $bid . '/configure', 0, t('Custom block configure link found.'));
-    $this->assertLinkByHref('admin/structure/block/manage/block/' . $bid . '/delete', 0, t('Custom block delete link found.'));
+    $this->assertLinkByHref('admin/structure/block/manage/block/' . $bid . '/configure', 0, 'Custom block configure link found.');
+    $this->assertLinkByHref('admin/structure/block/manage/block/' . $bid . '/delete', 0, 'Custom block delete link found.');
 
     // Set visibility only for authenticated users, to verify delete functionality.
     $edit = array();
@@ -103,10 +103,10 @@ class BlockTestCase extends DrupalWebTestCase {
     // Delete the created custom block & verify that it's been deleted and no longer appearing on the page.
     $this->clickLink(t('delete'));
     $this->drupalPost('admin/structure/block/manage/block/' . $bid . '/delete', array(), t('Delete'));
-    $this->assertRaw(t('The block %title has been removed.', array('%title' => $custom_block['info'])), t('Custom block successfully deleted.'));
-    $this->assertNoText(t($custom_block['title']), t('Custom block no longer appears on page.'));
+    $this->assertRaw(t('The block %title has been removed.', array('%title' => $custom_block['info'])), 'Custom block successfully deleted.');
+    $this->assertNoText(t($custom_block['title']), 'Custom block no longer appears on page.');
     $count = db_query("SELECT 1 FROM {block_role} WHERE module = :module AND delta = :delta", array(':module' => $custom_block['module'], ':delta' => $custom_block['delta']))->fetchField();
-    $this->assertFalse($count, t('Table block_role being cleaned.'));
+    $this->assertFalse($count, 'Table block_role being cleaned.');
   }
 
   /**
@@ -130,20 +130,20 @@ class BlockTestCase extends DrupalWebTestCase {
 
     // Confirm that the custom block is being displayed using configured text format.
     $this->drupalGet('node');
-    $this->assertRaw('<h1>Full HTML</h1>', t('Custom block successfully being displayed using Full HTML.'));
+    $this->assertRaw('<h1>Full HTML</h1>', 'Custom block successfully being displayed using Full HTML.');
 
     // Confirm that a user without access to Full HTML can not see the body field,
     // but can still submit the form without errors.
     $block_admin = $this->drupalCreateUser(array('administer blocks'));
     $this->drupalLogin($block_admin);
     $this->drupalGet('admin/structure/block/manage/block/' . $bid . '/configure');
-    $this->assertFieldByXPath("//textarea[@name='body[value]' and @disabled='disabled']", t('This field has been disabled because you do not have sufficient permissions to edit it.'), t('Body field contains denied message'));
+    $this->assertFieldByXPath("//textarea[@name='body[value]' and @disabled='disabled']", t('This field has been disabled because you do not have sufficient permissions to edit it.'), 'Body field contains denied message');
     $this->drupalPost('admin/structure/block/manage/block/' . $bid . '/configure', array(), t('Save block'));
     $this->assertNoText(t('Ensure that each block description is unique.'));
 
     // Confirm that the custom block is still being displayed using configured text format.
     $this->drupalGet('node');
-    $this->assertRaw('<h1>Full HTML</h1>', t('Custom block successfully being displayed using Full HTML.'));
+    $this->assertRaw('<h1>Full HTML</h1>', 'Custom block successfully being displayed using Full HTML.');
   }
 
   /**
@@ -178,18 +178,18 @@ class BlockTestCase extends DrupalWebTestCase {
     $this->moveBlockToRegion($block, $this->regions[1]);
 
     $this->drupalGet('');
-    $this->assertText($title, t('Block was displayed on the front page.'));
+    $this->assertText($title, 'Block was displayed on the front page.');
 
     $this->drupalGet('user');
-    $this->assertNoText($title, t('Block was not displayed according to block visibility rules.'));
+    $this->assertNoText($title, 'Block was not displayed according to block visibility rules.');
 
     $this->drupalGet('USER/' . $this->admin_user->uid);
-    $this->assertNoText($title, t('Block was not displayed according to block visibility rules regardless of path case.'));
+    $this->assertNoText($title, 'Block was not displayed according to block visibility rules regardless of path case.');
 
     // Confirm that the block is not displayed to anonymous users.
     $this->drupalLogout();
     $this->drupalGet('');
-    $this->assertNoText($title, t('Block was not displayed to anonymous users.'));
+    $this->assertNoText($title, 'Block was not displayed to anonymous users.');
   }
 
   /**
@@ -224,15 +224,15 @@ class BlockTestCase extends DrupalWebTestCase {
     $this->drupalPost('admin/structure/block/manage/' . $block['module'] . '/' . $block['delta'] . '/configure', $edit, t('Save block'));
 
     $this->drupalGet('');
-    $this->assertNoText($title, t('Block was not displayed according to block visibility rules.'));
+    $this->assertNoText($title, 'Block was not displayed according to block visibility rules.');
 
     $this->drupalGet('user');
-    $this->assertNoText($title, t('Block was not displayed according to block visibility rules regardless of path case.'));
+    $this->assertNoText($title, 'Block was not displayed according to block visibility rules regardless of path case.');
 
     // Confirm that the block is not displayed to anonymous users.
     $this->drupalLogout();
     $this->drupalGet('');
-    $this->assertNoText($title, t('Block was not displayed to anonymous users.'));
+    $this->assertNoText($title, 'Block was not displayed to anonymous users.');
   }
 
   /**
@@ -270,7 +270,7 @@ class BlockTestCase extends DrupalWebTestCase {
     $this->drupalPost('user/' . $this->admin_user->uid . '/edit', $edit, t('Save'));
 
     $this->drupalGet('');
-    $this->assertNoText($block['title'], t('Block was not displayed according to per user block visibility setting.'));
+    $this->assertNoText($block['title'], 'Block was not displayed according to per user block visibility setting.');
 
     // Set the block to be customizable per user, hidden by default.
     $edit = array();
@@ -283,7 +283,7 @@ class BlockTestCase extends DrupalWebTestCase {
     $this->drupalPost('user/' . $this->admin_user->uid . '/edit', $edit, t('Save'));
 
     $this->drupalGet('');
-    $this->assertText($block['title'], t('Block was displayed according to per user block visibility setting.'));
+    $this->assertText($block['title'], 'Block was displayed according to per user block visibility setting.');
   }
 
   /**
@@ -298,14 +298,14 @@ class BlockTestCase extends DrupalWebTestCase {
 
     // Set block title to confirm that interface works and override any custom titles.
     $this->drupalPost('admin/structure/block/manage/' . $block['module'] . '/' . $block['delta'] . '/configure', array('title' => $block['title']), t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), t('Block title set.'));
+    $this->assertText(t('The block configuration has been saved.'), 'Block title set.');
     $bid = db_query("SELECT bid FROM {block} WHERE module = :module AND delta = :delta", array(
       ':module' => $block['module'],
       ':delta' => $block['delta'],
     ))->fetchField();
 
     // Check to see if the block was created by checking that it's in the database.
-    $this->assertNotNull($bid, t('Block found in database'));
+    $this->assertNotNull($bid, 'Block found in database');
 
     // Check whether the block can be moved to all available regions.
     foreach ($this->regions as $region) {
@@ -318,21 +318,21 @@ class BlockTestCase extends DrupalWebTestCase {
     $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
 
     // Confirm that the block was moved to the proper region.
-    $this->assertText(t('The block settings have been updated.'), t('Block successfully move to disabled region.'));
-    $this->assertNoText(t($block['title']), t('Block no longer appears on page.'));
+    $this->assertText(t('The block settings have been updated.'), 'Block successfully move to disabled region.');
+    $this->assertNoText(t($block['title']), 'Block no longer appears on page.');
 
     // Confirm that the region's xpath is not available.
     $xpath = $this->buildXPathQuery('//div[@id=:id]/*', array(':id' => 'block-block-' . $bid));
-    $this->assertNoFieldByXPath($xpath, FALSE, t('Custom block found in no regions.'));
+    $this->assertNoFieldByXPath($xpath, FALSE, 'Custom block found in no regions.');
 
     // For convenience of developers, put the navigation block back.
     $edit = array();
     $edit['blocks[' . $block['module'] . '_' . $block['delta'] . '][region]'] = $this->regions[1];
     $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
-    $this->assertText(t('The block settings have been updated.'), t('Block successfully move to first sidebar region.'));
+    $this->assertText(t('The block settings have been updated.'), 'Block successfully move to first sidebar region.');
 
     $this->drupalPost('admin/structure/block/manage/' . $block['module'] . '/' . $block['delta'] . '/configure', array('title' => 'Navigation'), t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), t('Block title set.'));
+    $this->assertText(t('The block configuration has been saved.'), 'Block title set.');
   }
 
   function moveBlockToRegion($block, $region) {
@@ -342,18 +342,18 @@ class BlockTestCase extends DrupalWebTestCase {
     $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
 
     // Confirm that the block was moved to the proper region.
-    $this->assertText(t('The block settings have been updated.'), t('Block successfully moved to %region_name region.', array( '%region_name' => $region)));
+    $this->assertText(t('The block settings have been updated.'), format_string('Block successfully moved to %region_name region.', array( '%region_name' => $region)));
 
     // Confirm that the block is being displayed.
     $this->drupalGet('node');
-    $this->assertText(t($block['title']), t('Block successfully being displayed on the page.'));
+    $this->assertText(t($block['title']), 'Block successfully being displayed on the page.');
 
     // Confirm that the custom block was found at the proper region.
     $xpath = $this->buildXPathQuery('//div[@class=:region-class]//div[@id=:block-id]/*', array(
       ':region-class' => 'region region-' . str_replace('_', '-', $region),
       ':block-id' => 'block-' . $block['module'] . '-' . $block['delta'],
     ));
-    $this->assertFieldByXPath($xpath, NULL, t('Custom block found in %region_name region.', array('%region_name' => $region)));
+    $this->assertFieldByXPath($xpath, NULL, format_string('Custom block found in %region_name region.', array('%region_name' => $region)));
   }
 
   /**
@@ -361,14 +361,14 @@ class BlockTestCase extends DrupalWebTestCase {
    */
   function testBlockRehash() {
     module_enable(array('block_test'));
-    $this->assertTrue(module_exists('block_test'), t('Test block module enabled.'));
+    $this->assertTrue(module_exists('block_test'), 'Test block module enabled.');
 
     // Our new block should be inserted in the database when we visit the
     // block management page.
     $this->drupalGet('admin/structure/block');
     // Our test block's caching should default to DRUPAL_CACHE_PER_ROLE.
     $current_caching = db_query("SELECT cache FROM {block} WHERE module = 'block_test' AND delta = 'test_cache'")->fetchField();
-    $this->assertEqual($current_caching, DRUPAL_CACHE_PER_ROLE, t('Test block cache mode defaults to DRUPAL_CACHE_PER_ROLE.'));
+    $this->assertEqual($current_caching, DRUPAL_CACHE_PER_ROLE, 'Test block cache mode defaults to DRUPAL_CACHE_PER_ROLE.');
 
     // Disable caching for this block.
     variable_set('block_test_caching', DRUPAL_NO_CACHE);
@@ -376,7 +376,7 @@ class BlockTestCase extends DrupalWebTestCase {
     drupal_flush_all_caches();
     // Verify that the database is updated with the new caching mode.
     $current_caching = db_query("SELECT cache FROM {block} WHERE module = 'block_test' AND delta = 'test_cache'")->fetchField();
-    $this->assertEqual($current_caching, DRUPAL_NO_CACHE, t("Test block's database entry updated to DRUPAL_NO_CACHE."));
+    $this->assertEqual($current_caching, DRUPAL_NO_CACHE, "Test block's database entry updated to DRUPAL_NO_CACHE.");
   }
 }
 
@@ -427,7 +427,7 @@ class NewDefaultThemeBlocks extends DrupalWebTestCase {
       $themes['admin'] = $admin_theme;
     }
     $count = db_query_range('SELECT 1 FROM {block} WHERE theme NOT IN (:themes)', 0, 1, array(':themes' => $themes))->fetchField();
-    $this->assertFalse($count, t('Only the default theme and the admin theme have blocks.'));
+    $this->assertFalse($count, 'Only the default theme and the admin theme have blocks.');
 
     // Populate list of all blocks for matching against new theme.
     $blocks = array();
@@ -445,7 +445,7 @@ class NewDefaultThemeBlocks extends DrupalWebTestCase {
     $result = db_query('SELECT * FROM {block} WHERE theme = :theme', array(':theme' => 'stark'));
     foreach ($result as $block) {
       unset($block->theme, $block->bid);
-      $this->assertEqual($blocks[$block->module][$block->delta], $block, t('Block %name matched', array('%name' => $block->module . '-' . $block->delta)));
+      $this->assertEqual($blocks[$block->module][$block->delta], $block, format_string('Block %name matched', array('%name' => $block->module . '-' . $block->delta)));
     }
   }
 }
@@ -472,13 +472,13 @@ class BlockAdminThemeTestCase extends DrupalWebTestCase {
 
     // Ensure that access to block admin page is denied when theme is disabled.
     $this->drupalGet('admin/structure/block/list/stark');
-    $this->assertResponse(403, t('The block admin page for a disabled theme can not be accessed'));
+    $this->assertResponse(403, 'The block admin page for a disabled theme can not be accessed');
 
     // Enable admin theme and confirm that tab is accessible.
     $edit['admin_theme'] = 'stark';
     $this->drupalPost('admin/appearance', $edit, t('Save configuration'));
     $this->drupalGet('admin/structure/block/list/stark');
-    $this->assertResponse(200, t('The block admin page for the admin theme can be accessed'));
+    $this->assertResponse(200, 'The block admin page for the admin theme can be accessed');
   }
 }
 
@@ -532,20 +532,20 @@ class BlockCacheTestCase extends DrupalWebTestCase {
     variable_set('block_test_content', $current_content);
     $this->drupalLogin($this->normal_user);
     $this->drupalGet('');
-    $this->assertText($current_content, t('Block content displays.'));
+    $this->assertText($current_content, 'Block content displays.');
 
     // Change the content, but the cached copy should still be served.
     $old_content = $current_content;
     $current_content = $this->randomName();
     variable_set('block_test_content', $current_content);
     $this->drupalGet('');
-    $this->assertText($old_content, t('Block is served from the cache.'));
+    $this->assertText($old_content, 'Block is served from the cache.');
 
     // Clear the cache and verify that the stale data is no longer there.
     cache_clear_all();
     $this->drupalGet('');
-    $this->assertNoText($old_content, t('Block cache clear removes stale cache data.'));
-    $this->assertText($current_content, t('Fresh block content is displayed after clearing the cache.'));
+    $this->assertNoText($old_content, 'Block cache clear removes stale cache data.');
+    $this->assertText($current_content, 'Fresh block content is displayed after clearing the cache.');
 
     // Test whether the cached data is served for the correct users.
     $old_content = $current_content;
@@ -553,19 +553,19 @@ class BlockCacheTestCase extends DrupalWebTestCase {
     variable_set('block_test_content', $current_content);
     $this->drupalLogout();
     $this->drupalGet('');
-    $this->assertNoText($old_content, t('Anonymous user does not see content cached per-role for normal user.'));
+    $this->assertNoText($old_content, 'Anonymous user does not see content cached per-role for normal user.');
 
     $this->drupalLogin($this->normal_user_alt);
     $this->drupalGet('');
-    $this->assertText($old_content, t('User with the same roles sees per-role cached content.'));
+    $this->assertText($old_content, 'User with the same roles sees per-role cached content.');
 
     $this->drupalLogin($this->admin_user);
     $this->drupalGet('');
-    $this->assertNoText($old_content, t('Admin user does not see content cached per-role for normal user.'));
+    $this->assertNoText($old_content, 'Admin user does not see content cached per-role for normal user.');
 
     $this->drupalLogin($this->normal_user);
     $this->drupalGet('');
-    $this->assertText($old_content, t('Block is served from the per-role cache.'));
+    $this->assertText($old_content, 'Block is served from the per-role cache.');
   }
 
   /**
@@ -577,7 +577,7 @@ class BlockCacheTestCase extends DrupalWebTestCase {
     variable_set('block_test_content', $current_content);
 
     $this->drupalGet('');
-    $this->assertText($current_content, t('Block content displays.'));
+    $this->assertText($current_content, 'Block content displays.');
 
     $old_content = $current_content;
     $current_content = $this->randomName();
@@ -585,7 +585,7 @@ class BlockCacheTestCase extends DrupalWebTestCase {
 
     $this->drupalLogout();
     $this->drupalGet('user');
-    $this->assertText($old_content, t('Block content served from global cache.'));
+    $this->assertText($old_content, 'Block content served from global cache.');
   }
 
   /**
@@ -598,13 +598,13 @@ class BlockCacheTestCase extends DrupalWebTestCase {
 
     // If DRUPAL_NO_CACHE has no effect, the next request would be cached.
     $this->drupalGet('');
-    $this->assertText($current_content, t('Block content displays.'));
+    $this->assertText($current_content, 'Block content displays.');
 
     // A cached copy should not be served.
     $current_content = $this->randomName();
     variable_set('block_test_content', $current_content);
     $this->drupalGet('');
-    $this->assertText($current_content, t('DRUPAL_NO_CACHE prevents blocks from being cached.'));
+    $this->assertText($current_content, 'DRUPAL_NO_CACHE prevents blocks from being cached.');
   }
 
   /**
@@ -617,22 +617,22 @@ class BlockCacheTestCase extends DrupalWebTestCase {
     $this->drupalLogin($this->normal_user);
 
     $this->drupalGet('');
-    $this->assertText($current_content, t('Block content displays.'));
+    $this->assertText($current_content, 'Block content displays.');
 
     $old_content = $current_content;
     $current_content = $this->randomName();
     variable_set('block_test_content', $current_content);
 
     $this->drupalGet('');
-    $this->assertText($old_content, t('Block is served from per-user cache.'));
+    $this->assertText($old_content, 'Block is served from per-user cache.');
 
     $this->drupalLogin($this->normal_user_alt);
     $this->drupalGet('');
-    $this->assertText($current_content, t('Per-user block cache is not served for other users.'));
+    $this->assertText($current_content, 'Per-user block cache is not served for other users.');
 
     $this->drupalLogin($this->normal_user);
     $this->drupalGet('');
-    $this->assertText($old_content, t('Per-user block cache is persistent.'));
+    $this->assertText($old_content, 'Per-user block cache is persistent.');
   }
 
   /**
@@ -644,16 +644,16 @@ class BlockCacheTestCase extends DrupalWebTestCase {
     variable_set('block_test_content', $current_content);
 
     $this->drupalGet('node');
-    $this->assertText($current_content, t('Block content displays on the node page.'));
+    $this->assertText($current_content, 'Block content displays on the node page.');
 
     $old_content = $current_content;
     $current_content = $this->randomName();
     variable_set('block_test_content', $current_content);
 
     $this->drupalGet('user');
-    $this->assertNoText($old_content, t('Block content cached for the node page does not show up for the user page.'));
+    $this->assertNoText($old_content, 'Block content cached for the node page does not show up for the user page.');
     $this->drupalGet('node');
-    $this->assertText($old_content, t('Block content cached for the node page.'));
+    $this->assertText($old_content, 'Block content cached for the node page.');
   }
 
   /**
@@ -706,7 +706,7 @@ class BlockHTMLIdTestCase extends DrupalWebTestCase {
    */
   function testHTMLId() {
     $this->drupalGet('');
-    $this->assertRaw('block-block-test-test-html-id', t('HTML id for test block is valid.'));
+    $this->assertRaw('block-block-test-test-html-id', 'HTML id for test block is valid.');
   }
 }
 
@@ -736,7 +736,7 @@ class BlockTemplateSuggestionsUnitTest extends DrupalUnitTestCase {
     $variables1['elements']['#block'] = $block1;
     $variables1['elements']['#children'] = '';
     template_preprocess_block($variables1);
-    $this->assertEqual($variables1['theme_hook_suggestions'], array('block__footer', 'block__block', 'block__block__underscore_test'), t('Found expected block suggestions for delta with underscore'));
+    $this->assertEqual($variables1['theme_hook_suggestions'], array('block__footer', 'block__block', 'block__block__underscore_test'), 'Found expected block suggestions for delta with underscore');
 
     // Define block delta with hyphens to be preprocessed. Hyphens should be
     // replaced with underscores.
@@ -748,7 +748,7 @@ class BlockTemplateSuggestionsUnitTest extends DrupalUnitTestCase {
     $variables2['elements']['#block'] = $block2;
     $variables2['elements']['#children'] = '';
     template_preprocess_block($variables2);
-    $this->assertEqual($variables2['theme_hook_suggestions'], array('block__footer', 'block__block', 'block__block__hyphen_test'), t('Hyphens (-) in block delta were replaced by underscore (_)'));
+    $this->assertEqual($variables2['theme_hook_suggestions'], array('block__footer', 'block__block', 'block__block__hyphen_test'), 'Hyphens (-) in block delta were replaced by underscore (_)');
   }
 }
 
@@ -784,11 +784,11 @@ class BlockHiddenRegionTestCase extends DrupalWebTestCase {
 
     // Ensure that "block_test_theme" is set as the default theme.
     $this->drupalGet('admin/structure/block');
-    $this->assertText('Block test theme(' . t('active tab') . ')', t('Default local task on blocks admin page is the block test theme.'));
+    $this->assertText('Block test theme(' . t('active tab') . ')', 'Default local task on blocks admin page is the block test theme.');
 
     // Ensure that the search form block is displayed.
     $this->drupalGet('');
-    $this->assertText('Search form', t('Block was displayed on the front page.'));
+    $this->assertText('Search form', 'Block was displayed on the front page.');
   }
 }
 

+ 3 - 3
modules/block/tests/block_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 3 - 3
modules/block/tests/themes/block_test_theme/block_test_theme.info

@@ -13,8 +13,8 @@ regions[footer] = Footer
 regions[highlighted] = Highlighted
 regions[help] = Help
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 3 - 3
modules/blog/blog.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 files[] = blog.test
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 1 - 1
modules/book/book.admin.inc

@@ -278,5 +278,5 @@ function theme_book_admin_table($variables) {
     $rows[] = $row;
   }
 
-  return theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'book-outline')));
+  return theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'book-outline'), 'empty' => t('No book content available.')));
 }

+ 3 - 3
modules/book/book.info

@@ -7,8 +7,8 @@ files[] = book.test
 configure = admin/content/book/settings
 stylesheets[all][] = book.css
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 6 - 0
modules/book/book.js

@@ -1,3 +1,9 @@
+/**
+ * @file
+ * Javascript behaviors for the Book module.
+ */
+
+
 (function ($) {
 
 Drupal.behaviors.bookFieldsetSummaries = {

+ 3 - 3
modules/color/color.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 files[] = color.test
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 2 - 1
modules/comment/comment-wrapper.tpl.php

@@ -32,7 +32,8 @@
  *   into a string within the variable $classes.
  *
  * @see template_preprocess_comment_wrapper()
- * @see theme_comment_wrapper()
+ *
+ * @ingroup themeable
  */
 ?>
 <div id="comments" class="<?php print $classes; ?>"<?php print $attributes; ?>>

+ 3 - 3
modules/comment/comment.info

@@ -9,8 +9,8 @@ files[] = comment.test
 configure = admin/content/comment
 stylesheets[all][] = comment.css
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 13 - 2
modules/comment/comment.module

@@ -152,7 +152,7 @@ function comment_node_type_load($name) {
 }
 
 /**
- * Entity uri callback.
+ * Entity URI callback.
  */
 function comment_uri($comment) {
   return array(
@@ -992,6 +992,14 @@ function comment_build_content($comment, $node, $view_mode = 'full', $langcode =
   // Remove previously built content, if exists.
   $comment->content = array();
 
+  // Allow modules to change the view mode.
+  $context = array(
+    'entity_type' => 'comment',
+    'entity' => $comment,
+    'langcode' => $langcode,
+  );
+  drupal_alter('entity_view_mode', $view_mode, $context);
+
   // Build fields content.
   field_attach_prepare_view('comment', array($comment->cid => $comment), $view_mode, $langcode);
   entity_prepare_view('comment', array($comment->cid => $comment), $langcode);
@@ -1013,6 +1021,10 @@ function comment_build_content($comment, $node, $view_mode = 'full', $langcode =
   // Allow modules to make their own additions to the comment.
   module_invoke_all('comment_view', $comment, $view_mode, $langcode);
   module_invoke_all('entity_view', $comment, 'comment', $view_mode, $langcode);
+
+  // Make sure the current view mode is stored if no module has already
+  // populated the related key.
+  $comment->content += array('#view_mode' => $view_mode);
 }
 
 /**
@@ -2375,7 +2387,6 @@ function theme_comment_post_forbidden($variables) {
  * Process variables for comment-wrapper.tpl.php.
  *
  * @see comment-wrapper.tpl.php
- * @see theme_comment_wrapper()
  */
 function template_preprocess_comment_wrapper(&$variables) {
   // Provide contextual information.

+ 187 - 185
modules/comment/comment.test

@@ -1,7 +1,7 @@
 <?php
 
 /**
- * @file 
+ * @file
  * Tests for comment.module.
  */
 
@@ -48,7 +48,7 @@ class CommentHelperCase extends DrupalWebTestCase {
       $edit['subject'] = $subject;
     }
     else {
-      $this->assertNoFieldByName('subject', '', t('Subject field not found.'));
+      $this->assertNoFieldByName('subject', '', 'Subject field not found.');
     }
 
     if ($contact !== NULL && is_array($contact)) {
@@ -57,19 +57,19 @@ class CommentHelperCase extends DrupalWebTestCase {
     switch ($preview_mode) {
       case DRUPAL_REQUIRED:
         // Preview required so no save button should be found.
-        $this->assertNoFieldByName('op', t('Save'), t('Save button not found.'));
+        $this->assertNoFieldByName('op', t('Save'), 'Save button not found.');
         $this->drupalPost(NULL, $edit, t('Preview'));
         // Don't break here so that we can test post-preview field presence and
         // function below.
       case DRUPAL_OPTIONAL:
-        $this->assertFieldByName('op', t('Preview'), t('Preview button found.'));
-        $this->assertFieldByName('op', t('Save'), t('Save button found.'));
+        $this->assertFieldByName('op', t('Preview'), 'Preview button found.');
+        $this->assertFieldByName('op', t('Save'), 'Save button found.');
         $this->drupalPost(NULL, $edit, t('Save'));
         break;
 
       case DRUPAL_DISABLED:
-        $this->assertNoFieldByName('op', t('Preview'), t('Preview button not found.'));
-        $this->assertFieldByName('op', t('Save'), t('Save button found.'));
+        $this->assertNoFieldByName('op', t('Preview'), 'Preview button not found.');
+        $this->assertFieldByName('op', t('Save'), 'Save button found.');
         $this->drupalPost(NULL, $edit, t('Save'));
         break;
     }
@@ -83,7 +83,7 @@ class CommentHelperCase extends DrupalWebTestCase {
         $this->assertText($subject, 'Comment subject posted.');
       }
       $this->assertText($comment, 'Comment body posted.');
-      $this->assertTrue((!empty($match) && !empty($match[1])), t('Comment id found.'));
+      $this->assertTrue((!empty($match) && !empty($match[1])), 'Comment id found.');
     }
 
     if (isset($match[1])) {
@@ -122,7 +122,7 @@ class CommentHelperCase extends DrupalWebTestCase {
    */
   function deleteComment($comment) {
     $this->drupalPost('comment/' . $comment->id . '/delete', array(), t('Delete'));
-    $this->assertText(t('The comment and all its replies have been deleted.'), t('Comment deleted.'));
+    $this->assertText(t('The comment and all its replies have been deleted.'), 'Comment deleted.');
   }
 
   /**
@@ -200,7 +200,8 @@ class CommentHelperCase extends DrupalWebTestCase {
    */
   function setCommentSettings($name, $value, $message) {
     variable_set($name . '_article', $value);
-    $this->assertTrue(TRUE, t($message)); // Display status message.
+    // Display status message.
+    $this->assertTrue(TRUE, $message);
   }
 
   /**
@@ -230,10 +231,10 @@ class CommentHelperCase extends DrupalWebTestCase {
 
     if ($operation == 'delete') {
       $this->drupalPost(NULL, array(), t('Delete comments'));
-      $this->assertRaw(format_plural(1, 'Deleted 1 comment.', 'Deleted @count comments.'), t('Operation "' . $operation . '" was performed on comment.'));
+      $this->assertRaw(format_plural(1, 'Deleted 1 comment.', 'Deleted @count comments.'), format_string('Operation @operation was performed on comment.', array('@operation' => $operation)));
     }
     else {
-      $this->assertText(t('The update has been performed.'), t('Operation "' . $operation . '" was performed on comment.'));
+      $this->assertText(t('The update has been performed.'), format_string('Operation @operation was performed on comment.', array('@operation' => $operation)));
     }
   }
 
@@ -280,7 +281,7 @@ class CommentInterfaceTest extends CommentHelperCase {
     $comment_text = $this->randomName();
     $comment = $this->postComment($this->node, $comment_text);
     $comment_loaded = comment_load($comment->id);
-    $this->assertTrue($this->commentExists($comment), t('Comment found.'));
+    $this->assertTrue($this->commentExists($comment), 'Comment found.');
 
     // Set comments to have subject and preview to required.
     $this->drupalLogout();
@@ -295,12 +296,12 @@ class CommentInterfaceTest extends CommentHelperCase {
     $comment_text = $this->randomName();
     $comment = $this->postComment($this->node, $comment_text, $subject_text, TRUE);
     $comment_loaded = comment_load($comment->id);
-    $this->assertTrue($this->commentExists($comment), t('Comment found.'));
+    $this->assertTrue($this->commentExists($comment), 'Comment found.');
 
     // Check comment display.
     $this->drupalGet('node/' . $this->node->nid . '/' . $comment->id);
-    $this->assertText($subject_text, t('Individual comment subject found.'));
-    $this->assertText($comment_text, t('Individual comment body found.'));
+    $this->assertText($subject_text, 'Individual comment subject found.');
+    $this->assertText($comment_text, 'Individual comment body found.');
 
     // Set comments to have subject and preview to optional.
     $this->drupalLogout();
@@ -312,20 +313,20 @@ class CommentInterfaceTest extends CommentHelperCase {
     $this->drupalGet('comment/' . $comment->id . '/edit');
     $comment = $this->postComment(NULL, $comment->comment, $comment->subject, array('name' => ''));
     $comment_loaded = comment_load($comment->id);
-    $this->assertTrue(empty($comment_loaded->name) && $comment_loaded->uid == 0, t('Comment author successfully changed to anonymous.'));
+    $this->assertTrue(empty($comment_loaded->name) && $comment_loaded->uid == 0, 'Comment author successfully changed to anonymous.');
 
     // Test changing the comment author to an unverified user.
     $random_name = $this->randomName();
     $this->drupalGet('comment/' . $comment->id . '/edit');
     $comment = $this->postComment(NULL, $comment->comment, $comment->subject, array('name' => $random_name));
     $this->drupalGet('node/' . $this->node->nid);
-    $this->assertText($random_name . ' (' . t('not verified') . ')', t('Comment author successfully changed to an unverified user.'));
+    $this->assertText($random_name . ' (' . t('not verified') . ')', 'Comment author successfully changed to an unverified user.');
 
     // Test changing the comment author to a verified user.
     $this->drupalGet('comment/' . $comment->id . '/edit');
     $comment = $this->postComment(NULL, $comment->comment, $comment->subject, array('name' => $this->web_user->name));
     $comment_loaded = comment_load($comment->id);
-    $this->assertTrue($comment_loaded->name == $this->web_user->name && $comment_loaded->uid == $this->web_user->uid, t('Comment author successfully changed to a registered user.'));
+    $this->assertTrue($comment_loaded->name == $this->web_user->name && $comment_loaded->uid == $this->web_user->uid, 'Comment author successfully changed to a registered user.');
 
     $this->drupalLogout();
 
@@ -333,60 +334,60 @@ class CommentInterfaceTest extends CommentHelperCase {
     // subject though field enabled.
     $this->drupalLogin($this->web_user);
     $this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment->id);
-    $this->assertText($subject_text, t('Individual comment-reply subject found.'));
-    $this->assertText($comment_text, t('Individual comment-reply body found.'));
+    $this->assertText($subject_text, 'Individual comment-reply subject found.');
+    $this->assertText($comment_text, 'Individual comment-reply body found.');
     $reply = $this->postComment(NULL, $this->randomName(), '', TRUE);
     $reply_loaded = comment_load($reply->id);
-    $this->assertTrue($this->commentExists($reply, TRUE), t('Reply found.'));
-    $this->assertEqual($comment->id, $reply_loaded->pid, t('Pid of a reply to a comment is set correctly.'));
-    $this->assertEqual(rtrim($comment_loaded->thread, '/') . '.00/', $reply_loaded->thread, t('Thread of reply grows correctly.'));
+    $this->assertTrue($this->commentExists($reply, TRUE), 'Reply found.');
+    $this->assertEqual($comment->id, $reply_loaded->pid, 'Pid of a reply to a comment is set correctly.');
+    $this->assertEqual(rtrim($comment_loaded->thread, '/') . '.00/', $reply_loaded->thread, 'Thread of reply grows correctly.');
 
     // Second reply to comment #3 creating comment #4.
     $this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment->id);
-    $this->assertText($subject_text, t('Individual comment-reply subject found.'));
-    $this->assertText($comment_text, t('Individual comment-reply body found.'));
+    $this->assertText($subject_text, 'Individual comment-reply subject found.');
+    $this->assertText($comment_text, 'Individual comment-reply body found.');
     $reply = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE);
     $reply_loaded = comment_load($reply->id);
-    $this->assertTrue($this->commentExists($reply, TRUE), t('Second reply found.'));
-    $this->assertEqual(rtrim($comment_loaded->thread, '/') . '.01/', $reply_loaded->thread, t('Thread of second reply grows correctly.'));
+    $this->assertTrue($this->commentExists($reply, TRUE), 'Second reply found.');
+    $this->assertEqual(rtrim($comment_loaded->thread, '/') . '.01/', $reply_loaded->thread, 'Thread of second reply grows correctly.');
 
     // Edit reply.
     $this->drupalGet('comment/' . $reply->id . '/edit');
     $reply = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE);
-    $this->assertTrue($this->commentExists($reply, TRUE), t('Modified reply found.'));
+    $this->assertTrue($this->commentExists($reply, TRUE), 'Modified reply found.');
 
     // Correct link count
     $this->drupalGet('node');
-    $this->assertRaw('4 comments', t('Link to the 4 comments exist.'));
+    $this->assertRaw('4 comments', 'Link to the 4 comments exist.');
 
     // Confirm a new comment is posted to the correct page.
     $this->setCommentsPerPage(2);
     $comment_new_page = $this->postComment($this->node, $this->randomName(), $this->randomName(), TRUE);
-    $this->assertTrue($this->commentExists($comment_new_page), t('Page one exists. %s'));
+    $this->assertTrue($this->commentExists($comment_new_page), 'Page one exists. %s');
     $this->drupalGet('node/' . $this->node->nid, array('query' => array('page' => 1)));
-    $this->assertTrue($this->commentExists($reply, TRUE), t('Page two exists. %s'));
+    $this->assertTrue($this->commentExists($reply, TRUE), 'Page two exists. %s');
     $this->setCommentsPerPage(50);
 
     // Attempt to post to node with comments disabled.
     $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => COMMENT_NODE_HIDDEN));
-    $this->assertTrue($this->node, t('Article node created.'));
+    $this->assertTrue($this->node, 'Article node created.');
     $this->drupalGet('comment/reply/' . $this->node->nid);
-    $this->assertText('This discussion is closed', t('Posting to node with comments disabled'));
-    $this->assertNoField('edit-comment', t('Comment body field found.'));
+    $this->assertText('This discussion is closed', 'Posting to node with comments disabled');
+    $this->assertNoField('edit-comment', 'Comment body field found.');
 
     // Attempt to post to node with read-only comments.
     $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => COMMENT_NODE_CLOSED));
-    $this->assertTrue($this->node, t('Article node created.'));
+    $this->assertTrue($this->node, 'Article node created.');
     $this->drupalGet('comment/reply/' . $this->node->nid);
-    $this->assertText('This discussion is closed', t('Posting to node with comments read-only'));
-    $this->assertNoField('edit-comment', t('Comment body field found.'));
+    $this->assertText('This discussion is closed', 'Posting to node with comments read-only');
+    $this->assertNoField('edit-comment', 'Comment body field found.');
 
     // Attempt to post to node with comments enabled (check field names etc).
     $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => COMMENT_NODE_OPEN));
-    $this->assertTrue($this->node, t('Article node created.'));
+    $this->assertTrue($this->node, 'Article node created.');
     $this->drupalGet('comment/reply/' . $this->node->nid);
-    $this->assertNoText('This discussion is closed', t('Posting to node with comments enabled'));
-    $this->assertField('edit-comment-body-' . $langcode . '-0-value', t('Comment body field found.'));
+    $this->assertNoText('This discussion is closed', 'Posting to node with comments enabled');
+    $this->assertField('edit-comment-body-' . $langcode . '-0-value', 'Comment body field found.');
 
     // Delete comment and make sure that reply is also removed.
     $this->drupalLogout();
@@ -395,8 +396,8 @@ class CommentInterfaceTest extends CommentHelperCase {
     $this->deleteComment($comment_new_page);
 
     $this->drupalGet('node/' . $this->node->nid);
-    $this->assertFalse($this->commentExists($comment), t('Comment not found.'));
-    $this->assertFalse($this->commentExists($reply, TRUE), t('Reply not found.'));
+    $this->assertFalse($this->commentExists($comment), 'Comment not found.');
+    $this->assertFalse($this->commentExists($reply, TRUE), 'Reply not found.');
 
     // Enabled comment form on node page.
     $this->drupalLogin($this->admin_user);
@@ -407,7 +408,7 @@ class CommentInterfaceTest extends CommentHelperCase {
     $this->drupalLogin($this->web_user);
     $this->drupalGet('node/' . $this->node->nid);
     $form_comment = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE);
-    $this->assertTrue($this->commentExists($form_comment), t('Form comment found.'));
+    $this->assertTrue($this->commentExists($form_comment), 'Form comment found.');
 
     // Disable comment form on node page.
     $this->drupalLogout();
@@ -428,7 +429,7 @@ class CommentInterfaceTest extends CommentHelperCase {
     $this->assertNoLink(t('@count new comments', array('@count' => 0)));
     $this->assertLink(t('Read more'));
     $count = $this->xpath('//div[@id=:id]/div[@class=:class]/ul/li', array(':id' => 'node-' . $this->node->nid, ':class' => 'link-wrapper'));
-    $this->assertTrue(count($count) == 1, t('One child found'));
+    $this->assertTrue(count($count) == 1, 'One child found');
 
     // Create a new comment. This helper function may be run with different
     // comment settings so use comment_save() to avoid complex setup.
@@ -452,8 +453,8 @@ class CommentInterfaceTest extends CommentHelperCase {
     $this->drupalGet('node');
     $this->assertLink(t('1 new comment'));
     $this->clickLink(t('1 new comment'));
-    $this->assertRaw('<a id="new"></a>', t('Found "new" marker.'));
-    $this->assertTrue($this->xpath('//a[@id=:new]/following-sibling::a[1][@id=:comment_id]', array(':new' => 'new', ':comment_id' => 'comment-1')), t('The "new" anchor is positioned at the right comment.'));
+    $this->assertRaw('<a id="new"></a>', 'Found "new" marker.');
+    $this->assertTrue($this->xpath('//a[@id=:new]/following-sibling::a[1][@id=:comment_id]', array(':new' => 'new', ':comment_id' => 'comment-1')), 'The "new" anchor is positioned at the right comment.');
 
     // Test if "new comment" link is correctly removed.
     $this->drupalGet('node');
@@ -590,10 +591,10 @@ class CommentInterfaceTest extends CommentHelperCase {
 
     // Checks the initial values of node comment statistics with no comment.
     $node = node_load($this->node->nid);
-    $this->assertEqual($node->last_comment_timestamp, $this->node->created, t('The initial value of node last_comment_timestamp is the node created date.'));
-    $this->assertEqual($node->last_comment_name, NULL, t('The initial value of node last_comment_name is NULL.'));
-    $this->assertEqual($node->last_comment_uid, $this->web_user->uid, t('The initial value of node last_comment_uid is the node uid.'));
-    $this->assertEqual($node->comment_count, 0, t('The initial value of node comment_count is zero.'));
+    $this->assertEqual($node->last_comment_timestamp, $this->node->created, 'The initial value of node last_comment_timestamp is the node created date.');
+    $this->assertEqual($node->last_comment_name, NULL, 'The initial value of node last_comment_name is NULL.');
+    $this->assertEqual($node->last_comment_uid, $this->web_user->uid, 'The initial value of node last_comment_uid is the node uid.');
+    $this->assertEqual($node->comment_count, 0, 'The initial value of node comment_count is zero.');
 
     // Post comment #1 as web_user2.
     $this->drupalLogin($this->web_user2);
@@ -604,9 +605,9 @@ class CommentInterfaceTest extends CommentHelperCase {
     // Checks the new values of node comment statistics with comment #1.
     // The node needs to be reloaded with a node_load_multiple cache reset.
     $node = node_load($this->node->nid, NULL, TRUE);
-    $this->assertEqual($node->last_comment_name, NULL, t('The value of node last_comment_name is NULL.'));
-    $this->assertEqual($node->last_comment_uid, $this->web_user2->uid, t('The value of node last_comment_uid is the comment #1 uid.'));
-    $this->assertEqual($node->comment_count, 1, t('The value of node comment_count is 1.'));
+    $this->assertEqual($node->last_comment_name, NULL, 'The value of node last_comment_name is NULL.');
+    $this->assertEqual($node->last_comment_uid, $this->web_user2->uid, 'The value of node last_comment_uid is the comment #1 uid.');
+    $this->assertEqual($node->comment_count, 1, 'The value of node comment_count is 1.');
 
     // Prepare for anonymous comment submission (comment approval enabled).
     variable_set('user_register', USER_REGISTER_VISITORS);
@@ -629,9 +630,9 @@ class CommentInterfaceTest extends CommentHelperCase {
     // ensure they haven't changed since the comment has not been moderated.
     // The node needs to be reloaded with a node_load_multiple cache reset.
     $node = node_load($this->node->nid, NULL, TRUE);
-    $this->assertEqual($node->last_comment_name, NULL, t('The value of node last_comment_name is still NULL.'));
-    $this->assertEqual($node->last_comment_uid, $this->web_user2->uid, t('The value of node last_comment_uid is still the comment #1 uid.'));
-    $this->assertEqual($node->comment_count, 1, t('The value of node comment_count is still 1.'));
+    $this->assertEqual($node->last_comment_name, NULL, 'The value of node last_comment_name is still NULL.');
+    $this->assertEqual($node->last_comment_uid, $this->web_user2->uid, 'The value of node last_comment_uid is still the comment #1 uid.');
+    $this->assertEqual($node->comment_count, 1, 'The value of node comment_count is still 1.');
 
     // Prepare for anonymous comment submission (no approval required).
     $this->drupalLogin($this->admin_user);
@@ -650,9 +651,9 @@ class CommentInterfaceTest extends CommentHelperCase {
     // Checks the new values of node comment statistics with comment #3.
     // The node needs to be reloaded with a node_load_multiple cache reset.
     $node = node_load($this->node->nid, NULL, TRUE);
-    $this->assertEqual($node->last_comment_name, $comment_loaded->name, t('The value of node last_comment_name is the name of the anonymous user.'));
-    $this->assertEqual($node->last_comment_uid, 0, t('The value of node last_comment_uid is zero.'));
-    $this->assertEqual($node->comment_count, 2, t('The value of node comment_count is 2.'));
+    $this->assertEqual($node->last_comment_name, $comment_loaded->name, 'The value of node last_comment_name is the name of the anonymous user.');
+    $this->assertEqual($node->last_comment_uid, 0, 'The value of node last_comment_uid is zero.');
+    $this->assertEqual($node->comment_count, 2, 'The value of node comment_count is 2.');
   }
 
   /**
@@ -919,10 +920,10 @@ class CommentInterfaceTest extends CommentHelperCase {
         if ($path == "node/$nid") {
           $elements = $this->xpath('//form[@id=:id]', array(':id' => 'comment-form'));
           if ($info['form'] == COMMENT_FORM_BELOW) {
-            $this->assertTrue(count($elements), t('Comment form found below.'));
+            $this->assertTrue(count($elements), 'Comment form found below.');
           }
           else {
-            $this->assertFalse(count($elements), t('Comment form not found below.'));
+            $this->assertFalse(count($elements), 'Comment form not found below.');
           }
         }
       }
@@ -974,13 +975,13 @@ class CommentPreviewTest extends CommentHelperCase {
     $this->drupalPost('node/' . $this->node->nid, $edit, t('Preview'));
 
     // Check that the preview is displaying the title and body.
-    $this->assertTitle(t('Preview comment | Drupal'), t('Page title is "Preview comment".'));
-    $this->assertText($edit['subject'], t('Subject displayed.'));
-    $this->assertText($edit['comment_body[' . $langcode . '][0][value]'], t('Comment displayed.'));
+    $this->assertTitle(t('Preview comment | Drupal'), 'Page title is "Preview comment".');
+    $this->assertText($edit['subject'], 'Subject displayed.');
+    $this->assertText($edit['comment_body[' . $langcode . '][0][value]'], 'Comment displayed.');
 
     // Check that the title and body fields are displayed with the correct values.
-    $this->assertFieldByName('subject', $edit['subject'], t('Subject field displayed.'));
-    $this->assertFieldByName('comment_body[' . $langcode . '][0][value]', $edit['comment_body[' . $langcode . '][0][value]'], t('Comment field displayed.'));
+    $this->assertFieldByName('subject', $edit['subject'], 'Subject field displayed.');
+    $this->assertFieldByName('comment_body[' . $langcode . '][0][value]', $edit['comment_body[' . $langcode . '][0][value]'], 'Comment field displayed.');
 
     // Check that the signature is displaying with the correct text format.
     $this->assertLink($test_signature);
@@ -1013,28 +1014,28 @@ class CommentPreviewTest extends CommentHelperCase {
     $this->drupalPost('comment/' . $comment->id . '/edit', $edit, t('Preview'));
 
     // Check that the preview is displaying the subject, comment, author and date correctly.
-    $this->assertTitle(t('Preview comment | Drupal'), t('Page title is "Preview comment".'));
-    $this->assertText($edit['subject'], t('Subject displayed.'));
-    $this->assertText($edit['comment_body[' . $langcode . '][0][value]'], t('Comment displayed.'));
-    $this->assertText($edit['name'], t('Author displayed.'));
-    $this->assertText($expected_text_date, t('Date displayed.'));
+    $this->assertTitle(t('Preview comment | Drupal'), 'Page title is "Preview comment".');
+    $this->assertText($edit['subject'], 'Subject displayed.');
+    $this->assertText($edit['comment_body[' . $langcode . '][0][value]'], 'Comment displayed.');
+    $this->assertText($edit['name'], 'Author displayed.');
+    $this->assertText($expected_text_date, 'Date displayed.');
 
     // Check that the subject, comment, author and date fields are displayed with the correct values.
-    $this->assertFieldByName('subject', $edit['subject'], t('Subject field displayed.'));
-    $this->assertFieldByName('comment_body[' . $langcode . '][0][value]', $edit['comment_body[' . $langcode . '][0][value]'], t('Comment field displayed.'));
-    $this->assertFieldByName('name', $edit['name'], t('Author field displayed.'));
-    $this->assertFieldByName('date', $edit['date'], t('Date field displayed.'));
+    $this->assertFieldByName('subject', $edit['subject'], 'Subject field displayed.');
+    $this->assertFieldByName('comment_body[' . $langcode . '][0][value]', $edit['comment_body[' . $langcode . '][0][value]'], 'Comment field displayed.');
+    $this->assertFieldByName('name', $edit['name'], 'Author field displayed.');
+    $this->assertFieldByName('date', $edit['date'], 'Date field displayed.');
 
     // Check that saving a comment produces a success message.
     $this->drupalPost('comment/' . $comment->id . '/edit', $edit, t('Save'));
-    $this->assertText(t('Your comment has been posted.'), t('Comment posted.'));
+    $this->assertText(t('Your comment has been posted.'), 'Comment posted.');
 
     // Check that the comment fields are correct after loading the saved comment.
     $this->drupalGet('comment/' . $comment->id . '/edit');
-    $this->assertFieldByName('subject', $edit['subject'], t('Subject field displayed.'));
-    $this->assertFieldByName('comment_body[' . $langcode . '][0][value]', $edit['comment_body[' . $langcode . '][0][value]'], t('Comment field displayed.'));
-    $this->assertFieldByName('name', $edit['name'], t('Author field displayed.'));
-    $this->assertFieldByName('date', $expected_form_date, t('Date field displayed.'));
+    $this->assertFieldByName('subject', $edit['subject'], 'Subject field displayed.');
+    $this->assertFieldByName('comment_body[' . $langcode . '][0][value]', $edit['comment_body[' . $langcode . '][0][value]'], 'Comment field displayed.');
+    $this->assertFieldByName('name', $edit['name'], 'Author field displayed.');
+    $this->assertFieldByName('date', $expected_form_date, 'Date field displayed.');
 
     // Submit the form using the displayed values.
     $displayed = array();
@@ -1046,10 +1047,10 @@ class CommentPreviewTest extends CommentHelperCase {
 
     // Check that the saved comment is still correct.
     $comment_loaded = comment_load($comment->id);
-    $this->assertEqual($comment_loaded->subject, $edit['subject'], t('Subject loaded.'));
-    $this->assertEqual($comment_loaded->comment_body[$langcode][0]['value'], $edit['comment_body[' . $langcode . '][0][value]'], t('Comment body loaded.'));
-    $this->assertEqual($comment_loaded->name, $edit['name'], t('Name loaded.'));
-    $this->assertEqual($comment_loaded->created, $raw_date, t('Date loaded.'));
+    $this->assertEqual($comment_loaded->subject, $edit['subject'], 'Subject loaded.');
+    $this->assertEqual($comment_loaded->comment_body[$langcode][0]['value'], $edit['comment_body[' . $langcode . '][0][value]'], 'Comment body loaded.');
+    $this->assertEqual($comment_loaded->name, $edit['name'], 'Name loaded.');
+    $this->assertEqual($comment_loaded->created, $raw_date, 'Date loaded.');
 
   }
 
@@ -1085,7 +1086,7 @@ class CommentAnonymous extends CommentHelperCase {
 
     // Post anonymous comment without contact info.
     $anonymous_comment1 = $this->postComment($this->node, $this->randomName(), $this->randomName());
-    $this->assertTrue($this->commentExists($anonymous_comment1), t('Anonymous comment without contact info found.'));
+    $this->assertTrue($this->commentExists($anonymous_comment1), 'Anonymous comment without contact info found.');
 
     // Allow contact info.
     $this->drupalLogin($this->admin_user);
@@ -1094,15 +1095,15 @@ class CommentAnonymous extends CommentHelperCase {
     // Attempt to edit anonymous comment.
     $this->drupalGet('comment/' . $anonymous_comment1->id . '/edit');
     $edited_comment = $this->postComment(NULL, $this->randomName(), $this->randomName());
-    $this->assertTrue($this->commentExists($edited_comment, FALSE), t('Modified reply found.'));
+    $this->assertTrue($this->commentExists($edited_comment, FALSE), 'Modified reply found.');
     $this->drupalLogout();
 
     // Post anonymous comment with contact info (optional).
     $this->drupalGet('comment/reply/' . $this->node->nid);
-    $this->assertTrue($this->commentContactInfoAvailable(), t('Contact information available.'));
+    $this->assertTrue($this->commentContactInfoAvailable(), 'Contact information available.');
 
     $anonymous_comment2 = $this->postComment($this->node, $this->randomName(), $this->randomName());
-    $this->assertTrue($this->commentExists($anonymous_comment2), t('Anonymous comment with contact info (optional) found.'));
+    $this->assertTrue($this->commentExists($anonymous_comment2), 'Anonymous comment with contact info (optional) found.');
 
     // Ensure anonymous users cannot post in the name of registered users.
     $langcode = LANGUAGE_NONE;
@@ -1122,41 +1123,42 @@ class CommentAnonymous extends CommentHelperCase {
 
     // Try to post comment with contact info (required).
     $this->drupalGet('comment/reply/' . $this->node->nid);
-    $this->assertTrue($this->commentContactInfoAvailable(), t('Contact information available.'));
+    $this->assertTrue($this->commentContactInfoAvailable(), 'Contact information available.');
 
     $anonymous_comment3 = $this->postComment($this->node, $this->randomName(), $this->randomName(), TRUE);
-    $this->assertText(t('E-mail field is required.'), t('E-mail required.')); // Name should have 'Anonymous' for value by default.
-    $this->assertFalse($this->commentExists($anonymous_comment3), t('Anonymous comment with contact info (required) not found.'));
+    // Name should have 'Anonymous' for value by default.
+    $this->assertText(t('E-mail field is required.'), 'E-mail required.');
+    $this->assertFalse($this->commentExists($anonymous_comment3), 'Anonymous comment with contact info (required) not found.');
 
     // Post comment with contact info (required).
     $author_name = $this->randomName();
     $author_mail = $this->randomName() . '@example.com';
     $anonymous_comment3 = $this->postComment($this->node, $this->randomName(), $this->randomName(), array('name' => $author_name, 'mail' => $author_mail));
-    $this->assertTrue($this->commentExists($anonymous_comment3), t('Anonymous comment with contact info (required) found.'));
+    $this->assertTrue($this->commentExists($anonymous_comment3), 'Anonymous comment with contact info (required) found.');
 
     // Make sure the user data appears correctly when editing the comment.
     $this->drupalLogin($this->admin_user);
     $this->drupalGet('comment/' . $anonymous_comment3->id . '/edit');
-    $this->assertRaw($author_name, t("The anonymous user's name is correct when editing the comment."));
-    $this->assertRaw($author_mail, t("The anonymous user's e-mail address is correct when editing the comment."));
+    $this->assertRaw($author_name, "The anonymous user's name is correct when editing the comment.");
+    $this->assertRaw($author_mail, "The anonymous user's e-mail address is correct when editing the comment.");
 
     // Unpublish comment.
     $this->performCommentOperation($anonymous_comment3, 'unpublish');
 
     $this->drupalGet('admin/content/comment/approval');
-    $this->assertRaw('comments[' . $anonymous_comment3->id . ']', t('Comment was unpublished.'));
+    $this->assertRaw('comments[' . $anonymous_comment3->id . ']', 'Comment was unpublished.');
 
     // Publish comment.
     $this->performCommentOperation($anonymous_comment3, 'publish', TRUE);
 
     $this->drupalGet('admin/content/comment');
-    $this->assertRaw('comments[' . $anonymous_comment3->id . ']', t('Comment was published.'));
+    $this->assertRaw('comments[' . $anonymous_comment3->id . ']', 'Comment was published.');
 
     // Delete comment.
     $this->performCommentOperation($anonymous_comment3, 'delete');
 
     $this->drupalGet('admin/content/comment');
-    $this->assertNoRaw('comments[' . $anonymous_comment3->id . ']', t('Comment was deleted.'));
+    $this->assertNoRaw('comments[' . $anonymous_comment3->id . ']', 'Comment was deleted.');
     $this->drupalLogout();
 
     // Reset.
@@ -1170,14 +1172,14 @@ class CommentAnonymous extends CommentHelperCase {
     // NOTE: if authenticated user has permission to post comments, then a
     // "Login or register to post comments" type link may be shown.
     $this->drupalGet('node/' . $this->node->nid);
-    $this->assertNoPattern('@<h2[^>]*>Comments</h2>@', t('Comments were not displayed.'));
-    $this->assertNoLink('Add new comment', t('Link to add comment was found.'));
+    $this->assertNoPattern('@<h2[^>]*>Comments</h2>@', 'Comments were not displayed.');
+    $this->assertNoLink('Add new comment', 'Link to add comment was found.');
 
     // Attempt to view node-comment form while disallowed.
     $this->drupalGet('comment/reply/' . $this->node->nid);
-    $this->assertText('You are not authorized to post comments', t('Error attempting to post comment.'));
-    $this->assertNoFieldByName('subject', '', t('Subject field not found.'));
-    $this->assertNoFieldByName("comment_body[$langcode][0][value]", '', t('Comment field not found.'));
+    $this->assertText('You are not authorized to post comments', 'Error attempting to post comment.');
+    $this->assertNoFieldByName('subject', '', 'Subject field not found.');
+    $this->assertNoFieldByName("comment_body[$langcode][0][value]", '', 'Comment field not found.');
 
     user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array(
       'access comments' => TRUE,
@@ -1185,9 +1187,9 @@ class CommentAnonymous extends CommentHelperCase {
       'skip comment approval' => FALSE,
     ));
     $this->drupalGet('node/' . $this->node->nid);
-    $this->assertPattern('@<h2[^>]*>Comments</h2>@', t('Comments were displayed.'));
-    $this->assertLink('Log in', 1, t('Link to log in was found.'));
-    $this->assertLink('register', 1, t('Link to register was found.'));
+    $this->assertPattern('@<h2[^>]*>Comments</h2>@', 'Comments were displayed.');
+    $this->assertLink('Log in', 1, 'Link to log in was found.');
+    $this->assertLink('register', 1, 'Link to register was found.');
 
     user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array(
       'access comments' => FALSE,
@@ -1195,13 +1197,13 @@ class CommentAnonymous extends CommentHelperCase {
       'skip comment approval' => TRUE,
     ));
     $this->drupalGet('node/' . $this->node->nid);
-    $this->assertNoPattern('@<h2[^>]*>Comments</h2>@', t('Comments were not displayed.'));
-    $this->assertFieldByName('subject', '', t('Subject field found.'));
-    $this->assertFieldByName("comment_body[$langcode][0][value]", '', t('Comment field found.'));
+    $this->assertNoPattern('@<h2[^>]*>Comments</h2>@', 'Comments were not displayed.');
+    $this->assertFieldByName('subject', '', 'Subject field found.');
+    $this->assertFieldByName("comment_body[$langcode][0][value]", '', 'Comment field found.');
 
     $this->drupalGet('comment/reply/' . $this->node->nid . '/' . $anonymous_comment3->id);
-    $this->assertText('You are not authorized to view comments', t('Error attempting to post reply.'));
-    $this->assertNoText($author_name, t('Comment not displayed.'));
+    $this->assertText('You are not authorized to view comments', 'Error attempting to post reply.');
+    $this->assertNoText($author_name, 'Comment not displayed.');
   }
 }
 
@@ -1245,22 +1247,22 @@ class CommentPagerTest extends CommentHelperCase {
     // Check the first page of the node, and confirm the correct comments are
     // shown.
     $this->drupalGet('node/' . $node->nid);
-    $this->assertRaw(t('next'), t('Paging links found.'));
-    $this->assertTrue($this->commentExists($comments[0]), t('Comment 1 appears on page 1.'));
-    $this->assertFalse($this->commentExists($comments[1]), t('Comment 2 does not appear on page 1.'));
-    $this->assertFalse($this->commentExists($comments[2]), t('Comment 3 does not appear on page 1.'));
+    $this->assertRaw(t('next'), 'Paging links found.');
+    $this->assertTrue($this->commentExists($comments[0]), 'Comment 1 appears on page 1.');
+    $this->assertFalse($this->commentExists($comments[1]), 'Comment 2 does not appear on page 1.');
+    $this->assertFalse($this->commentExists($comments[2]), 'Comment 3 does not appear on page 1.');
 
     // Check the second page.
     $this->drupalGet('node/' . $node->nid, array('query' => array('page' => 1)));
-    $this->assertTrue($this->commentExists($comments[1]), t('Comment 2 appears on page 2.'));
-    $this->assertFalse($this->commentExists($comments[0]), t('Comment 1 does not appear on page 2.'));
-    $this->assertFalse($this->commentExists($comments[2]), t('Comment 3 does not appear on page 2.'));
+    $this->assertTrue($this->commentExists($comments[1]), 'Comment 2 appears on page 2.');
+    $this->assertFalse($this->commentExists($comments[0]), 'Comment 1 does not appear on page 2.');
+    $this->assertFalse($this->commentExists($comments[2]), 'Comment 3 does not appear on page 2.');
 
     // Check the third page.
     $this->drupalGet('node/' . $node->nid, array('query' => array('page' => 2)));
-    $this->assertTrue($this->commentExists($comments[2]), t('Comment 3 appears on page 3.'));
-    $this->assertFalse($this->commentExists($comments[0]), t('Comment 1 does not appear on page 3.'));
-    $this->assertFalse($this->commentExists($comments[1]), t('Comment 2 does not appear on page 3.'));
+    $this->assertTrue($this->commentExists($comments[2]), 'Comment 3 appears on page 3.');
+    $this->assertFalse($this->commentExists($comments[0]), 'Comment 1 does not appear on page 3.');
+    $this->assertFalse($this->commentExists($comments[1]), 'Comment 2 does not appear on page 3.');
 
     // Post a reply to the oldest comment and test again.
     $replies = array();
@@ -1272,21 +1274,21 @@ class CommentPagerTest extends CommentHelperCase {
     // We are still in flat view - the replies should not be on the first page,
     // even though they are replies to the oldest comment.
     $this->drupalGet('node/' . $node->nid, array('query' => array('page' => 0)));
-    $this->assertFalse($this->commentExists($reply, TRUE), t('In flat mode, reply does not appear on page 1.'));
+    $this->assertFalse($this->commentExists($reply, TRUE), 'In flat mode, reply does not appear on page 1.');
 
     // If we switch to threaded mode, the replies on the oldest comment
     // should be bumped to the first page and comment 6 should be bumped
     // to the second page.
     $this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, t('Switched to threaded mode.'));
     $this->drupalGet('node/' . $node->nid, array('query' => array('page' => 0)));
-    $this->assertTrue($this->commentExists($reply, TRUE), t('In threaded mode, reply appears on page 1.'));
-    $this->assertFalse($this->commentExists($comments[1]), t('In threaded mode, comment 2 has been bumped off of page 1.'));
+    $this->assertTrue($this->commentExists($reply, TRUE), 'In threaded mode, reply appears on page 1.');
+    $this->assertFalse($this->commentExists($comments[1]), 'In threaded mode, comment 2 has been bumped off of page 1.');
 
     // If (# replies > # comments per page) in threaded expanded view,
     // the overage should be bumped.
     $reply2 = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE);
     $this->drupalGet('node/' . $node->nid, array('query' => array('page' => 0)));
-    $this->assertFalse($this->commentExists($reply2, TRUE), t('In threaded mode where # replies > # comments per page, the newest reply does not appear on page 1.'));
+    $this->assertFalse($this->commentExists($reply2, TRUE), 'In threaded mode where # replies > # comments per page, the newest reply does not appear on page 1.');
 
     $this->drupalLogout();
   }
@@ -1388,7 +1390,7 @@ class CommentPagerTest extends CommentHelperCase {
       $result_order[] = substr($anchor['id'], 8);
     }
 
-    return $this->assertIdentical($expected_cids, $result_order, t('Comment order: expected @expected, returned @returned.', array('@expected' => implode(',', $expected_cids), '@returned' => implode(',', $result_order))));
+    return $this->assertIdentical($expected_cids, $result_order, format_string('Comment order: expected @expected, returned @returned.', array('@expected' => implode(',', $expected_cids), '@returned' => implode(',', $result_order))));
   }
 
   /**
@@ -1448,7 +1450,7 @@ class CommentPagerTest extends CommentHelperCase {
     foreach ($expected_pages as $new_replies => $expected_page) {
       $returned = comment_new_page_count($node->comment_count, $new_replies, $node);
       $returned_page = is_array($returned) ? $returned['page'] : 0;
-      $this->assertIdentical($expected_page, $returned_page, t('Flat mode, @new replies: expected page @expected, returned page @returned.', array('@new' => $new_replies, '@expected' => $expected_page, '@returned' => $returned_page)));
+      $this->assertIdentical($expected_page, $returned_page, format_string('Flat mode, @new replies: expected page @expected, returned page @returned.', array('@new' => $new_replies, '@expected' => $expected_page, '@returned' => $returned_page)));
     }
 
     $this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, t('Switched to threaded mode.'));
@@ -1466,7 +1468,7 @@ class CommentPagerTest extends CommentHelperCase {
     foreach ($expected_pages as $new_replies => $expected_page) {
       $returned = comment_new_page_count($node->comment_count, $new_replies, $node);
       $returned_page = is_array($returned) ? $returned['page'] : 0;
-      $this->assertEqual($expected_page, $returned_page, t('Threaded mode, @new replies: expected page @expected, returned page @returned.', array('@new' => $new_replies, '@expected' => $expected_page, '@returned' => $returned_page)));
+      $this->assertEqual($expected_page, $returned_page, format_string('Threaded mode, @new replies: expected page @expected, returned page @returned.', array('@new' => $new_replies, '@expected' => $expected_page, '@returned' => $returned_page)));
     }
   }
 }
@@ -1516,12 +1518,12 @@ class CommentNodeAccessTest extends CommentHelperCase {
     $comment_subject = $this->randomName();
     $comment = $this->postComment($this->node, $comment_text, $comment_subject);
     $comment_loaded = comment_load($comment->id);
-    $this->assertTrue($this->commentExists($comment), t('Comment found.'));
+    $this->assertTrue($this->commentExists($comment), 'Comment found.');
 
     // Check comment display.
     $this->drupalGet('node/' . $this->node->nid . '/' . $comment->id);
-    $this->assertText($comment_subject, t('Individual comment subject found.'));
-    $this->assertText($comment_text, t('Individual comment body found.'));
+    $this->assertText($comment_subject, 'Individual comment subject found.');
+    $this->assertText($comment_text, 'Individual comment body found.');
 
     // Reply to comment, creating second comment.
     $this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment->id);
@@ -1529,7 +1531,7 @@ class CommentNodeAccessTest extends CommentHelperCase {
     $reply_subject = $this->randomName();
     $reply = $this->postComment(NULL, $reply_text, $reply_subject, TRUE);
     $reply_loaded = comment_load($reply->id);
-    $this->assertTrue($this->commentExists($reply, TRUE), t('Reply found.'));
+    $this->assertTrue($this->commentExists($reply, TRUE), 'Reply found.');
 
     // Go to the node page and verify comment and reply are visible.
     $this->drupalGet('node/' . $this->node->nid);
@@ -1572,7 +1574,7 @@ class CommentApprovalTest extends CommentHelperCase {
     $subject = $this->randomName();
     $body = $this->randomName();
     $this->postComment($this->node, $body, $subject, TRUE); // Set $contact to true so that it won't check for id and message.
-    $this->assertText(t('Your comment has been queued for review by site administrators and will be published after approval.'), t('Comment requires approval.'));
+    $this->assertText(t('Your comment has been queued for review by site administrators and will be published after approval.'), 'Comment requires approval.');
 
     // Get unapproved comment id.
     $this->drupalLogin($this->admin_user);
@@ -1580,7 +1582,7 @@ class CommentApprovalTest extends CommentHelperCase {
     $anonymous_comment4 = (object) array('id' => $anonymous_comment4, 'subject' => $subject, 'comment' => $body);
     $this->drupalLogout();
 
-    $this->assertFalse($this->commentExists($anonymous_comment4), t('Anonymous comment was not published.'));
+    $this->assertFalse($this->commentExists($anonymous_comment4), 'Anonymous comment was not published.');
 
     // Approve comment.
     $this->drupalLogin($this->admin_user);
@@ -1588,7 +1590,7 @@ class CommentApprovalTest extends CommentHelperCase {
     $this->drupalLogout();
 
     $this->drupalGet('node/' . $this->node->nid);
-    $this->assertTrue($this->commentExists($anonymous_comment4), t('Anonymous comment visible.'));
+    $this->assertTrue($this->commentExists($anonymous_comment4), 'Anonymous comment visible.');
 
     // Post 2 anonymous comments without contact info.
     $comments[] = $this->postComment($this->node, $this->randomName(), $this->randomName(), TRUE);
@@ -1597,13 +1599,13 @@ class CommentApprovalTest extends CommentHelperCase {
     // Publish multiple comments in one operation.
     $this->drupalLogin($this->admin_user);
     $this->drupalGet('admin/content/comment/approval');
-    $this->assertText(t('Unapproved comments (@count)', array('@count' => 2)), t('Two unapproved comments waiting for approval.'));
+    $this->assertText(t('Unapproved comments (@count)', array('@count' => 2)), 'Two unapproved comments waiting for approval.');
     $edit = array(
       "comments[{$comments[0]->id}]" => 1,
       "comments[{$comments[1]->id}]" => 1,
     );
     $this->drupalPost(NULL, $edit, t('Update'));
-    $this->assertText(t('Unapproved comments (@count)', array('@count' => 0)), t('All comments were approved.'));
+    $this->assertText(t('Unapproved comments (@count)', array('@count' => 0)), 'All comments were approved.');
 
     // Delete multiple comments in one operation.
     $edit = array(
@@ -1613,9 +1615,9 @@ class CommentApprovalTest extends CommentHelperCase {
       "comments[{$anonymous_comment4->id}]" => 1,
     );
     $this->drupalPost(NULL, $edit, t('Update'));
-    $this->assertText(t('Are you sure you want to delete these comments and all their children?'), t('Confirmation required.'));
+    $this->assertText(t('Are you sure you want to delete these comments and all their children?'), 'Confirmation required.');
     $this->drupalPost(NULL, $edit, t('Delete comments'));
-    $this->assertText(t('No comments available.'), t('All comments were deleted.'));
+    $this->assertText(t('No comments available.'), 'All comments were deleted.');
   }
 
   /**
@@ -1636,7 +1638,7 @@ class CommentApprovalTest extends CommentHelperCase {
     $subject = $this->randomName();
     $body = $this->randomName();
     $this->postComment($this->node, $body, $subject, TRUE); // Set $contact to true so that it won't check for id and message.
-    $this->assertText(t('Your comment has been queued for review by site administrators and will be published after approval.'), t('Comment requires approval.'));
+    $this->assertText(t('Your comment has been queued for review by site administrators and will be published after approval.'), 'Comment requires approval.');
 
     // Get unapproved comment id.
     $this->drupalLogin($this->admin_user);
@@ -1644,20 +1646,20 @@ class CommentApprovalTest extends CommentHelperCase {
     $anonymous_comment4 = (object) array('id' => $anonymous_comment4, 'subject' => $subject, 'comment' => $body);
     $this->drupalLogout();
 
-    $this->assertFalse($this->commentExists($anonymous_comment4), t('Anonymous comment was not published.'));
+    $this->assertFalse($this->commentExists($anonymous_comment4), 'Anonymous comment was not published.');
 
     // Approve comment.
     $this->drupalLogin($this->admin_user);
     $this->drupalGet('comment/1/approve');
-    $this->assertResponse(403, t('Forged comment approval was denied.'));
+    $this->assertResponse(403, 'Forged comment approval was denied.');
     $this->drupalGet('comment/1/approve', array('query' => array('token' => 'forged')));
-    $this->assertResponse(403, t('Forged comment approval was denied.'));
+    $this->assertResponse(403, 'Forged comment approval was denied.');
     $this->drupalGet('node/' . $this->node->nid);
     $this->clickLink(t('approve'));
     $this->drupalLogout();
 
     $this->drupalGet('node/' . $this->node->nid);
-    $this->assertTrue($this->commentExists($anonymous_comment4), t('Anonymous comment visible.'));
+    $this->assertTrue($this->commentExists($anonymous_comment4), 'Anonymous comment visible.');
   }
 }
 
@@ -1684,7 +1686,7 @@ class CommentBlockFunctionalTest extends CommentHelperCase {
       'blocks[comment_recent][region]' => 'sidebar_first',
     );
     $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
-    $this->assertText(t('The block settings have been updated.'), t('Block saved to first sidebar region.'));
+    $this->assertText(t('The block settings have been updated.'), 'Block saved to first sidebar region.');
 
     // Set block title and variables.
     $block = array(
@@ -1692,7 +1694,7 @@ class CommentBlockFunctionalTest extends CommentHelperCase {
       'comment_block_count' => 2,
     );
     $this->drupalPost('admin/structure/block/manage/comment/recent/configure', $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), t('Block saved.'));
+    $this->assertText(t('The block configuration has been saved.'), 'Block saved.');
 
     // Add some test comments, one without a subject.
     $comment1 = $this->postComment($this->node, $this->randomName(), $this->randomName());
@@ -1704,20 +1706,20 @@ class CommentBlockFunctionalTest extends CommentHelperCase {
     $this->drupalLogout();
     user_role_revoke_permissions(DRUPAL_ANONYMOUS_RID, array('access comments'));
     $this->drupalGet('');
-    $this->assertNoText($block['title'], t('Block was not found.'));
+    $this->assertNoText($block['title'], 'Block was not found.');
     user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access comments'));
 
     // Test that a user with the 'access comments' permission can see the
     // block.
     $this->drupalLogin($this->web_user);
     $this->drupalGet('');
-    $this->assertText($block['title'], t('Block was found.'));
+    $this->assertText($block['title'], 'Block was found.');
 
     // Test the only the 2 latest comments are shown and in the proper order.
-    $this->assertNoText($comment1->subject, t('Comment not found in block.'));
-    $this->assertText($comment2->subject, t('Comment found in block.'));
-    $this->assertText($comment3->comment, t('Comment found in block.'));
-    $this->assertTrue(strpos($this->drupalGetContent(), $comment3->comment) < strpos($this->drupalGetContent(), $comment2->subject), t('Comments were ordered correctly in block.'));
+    $this->assertNoText($comment1->subject, 'Comment not found in block.');
+    $this->assertText($comment2->subject, 'Comment found in block.');
+    $this->assertText($comment3->comment, 'Comment found in block.');
+    $this->assertTrue(strpos($this->drupalGetContent(), $comment3->comment) < strpos($this->drupalGetContent(), $comment2->subject), 'Comments were ordered correctly in block.');
 
     // Set the number of recent comments to show to 10.
     $this->drupalLogout();
@@ -1726,30 +1728,30 @@ class CommentBlockFunctionalTest extends CommentHelperCase {
       'comment_block_count' => 10,
     );
     $this->drupalPost('admin/structure/block/manage/comment/recent/configure', $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), t('Block saved.'));
+    $this->assertText(t('The block configuration has been saved.'), 'Block saved.');
 
     // Post an additional comment.
     $comment4 = $this->postComment($this->node, $this->randomName(), $this->randomName());
 
     // Test that all four comments are shown.
-    $this->assertText($comment1->subject, t('Comment found in block.'));
-    $this->assertText($comment2->subject, t('Comment found in block.'));
-    $this->assertText($comment3->comment, t('Comment found in block.'));
-    $this->assertText($comment4->subject, t('Comment found in block.'));
+    $this->assertText($comment1->subject, 'Comment found in block.');
+    $this->assertText($comment2->subject, 'Comment found in block.');
+    $this->assertText($comment3->comment, 'Comment found in block.');
+    $this->assertText($comment4->subject, 'Comment found in block.');
 
     // Test that links to comments work when comments are across pages.
     $this->setCommentsPerPage(1);
     $this->drupalGet('');
     $this->clickLink($comment1->subject);
-    $this->assertText($comment1->subject, t('Comment link goes to correct page.'));
+    $this->assertText($comment1->subject, 'Comment link goes to correct page.');
     $this->drupalGet('');
     $this->clickLink($comment2->subject);
-    $this->assertText($comment2->subject, t('Comment link goes to correct page.'));
+    $this->assertText($comment2->subject, 'Comment link goes to correct page.');
     $this->clickLink($comment4->subject);
-    $this->assertText($comment4->subject, t('Comment link goes to correct page.'));
+    $this->assertText($comment4->subject, 'Comment link goes to correct page.');
     // Check that when viewing a comment page from a link to the comment, that
     // rel="canonical" is added to the head of the document.
-    $this->assertRaw('<link rel="canonical"', t('Canonical URL was found in the HTML head'));
+    $this->assertRaw('<link rel="canonical"', 'Canonical URL was found in the HTML head');
   }
 }
 
@@ -1774,13 +1776,13 @@ class CommentRSSUnitTest extends CommentHelperCase {
     $comment = $this->postComment($this->node, $this->randomName(), $this->randomName());
     $this->drupalGet('rss.xml');
     $raw = '<comments>' . url('node/' . $this->node->nid, array('fragment' => 'comments', 'absolute' => TRUE)) . '</comments>';
-    $this->assertRaw($raw, t('Comments as part of RSS feed.'));
+    $this->assertRaw($raw, 'Comments as part of RSS feed.');
 
     // Hide comments from RSS feed and check presence.
     $this->node->comment = COMMENT_NODE_HIDDEN;
     node_save($this->node);
     $this->drupalGet('rss.xml');
-    $this->assertNoRaw($raw, t('Hidden comments is not a part of RSS feed.'));
+    $this->assertNoRaw($raw, 'Hidden comments is not a part of RSS feed.');
   }
 }
 
@@ -1814,14 +1816,14 @@ class CommentContentRebuild extends CommentHelperCase {
     $comment_text = $this->randomName();
     $comment = $this->postComment($this->node, $comment_text, $subject_text, TRUE);
     $comment_loaded = comment_load($comment->id);
-    $this->assertTrue($this->commentExists($comment), t('Comment found.'));
+    $this->assertTrue($this->commentExists($comment), 'Comment found.');
 
     // Add the property to the content array and then see if it still exists on build.
     $comment_loaded->content['test_property'] = array('#value' => $this->randomString());
     $built_content = comment_view($comment_loaded, $this->node);
 
     // This means that the content was rebuilt as the added test property no longer exists.
-    $this->assertFalse(isset($built_content['test_property']), t('Comment content was emptied before being built.'));
+    $this->assertFalse(isset($built_content['test_property']), 'Comment content was emptied before being built.');
   }
 }
 
@@ -1887,11 +1889,11 @@ class CommentTokenReplaceTestCase extends CommentHelperCase {
     $tests['[comment:author:name]'] = check_plain($this->admin_user->name);
 
     // Test to make sure that we generated something for each token.
-    $this->assertFalse(in_array(0, array_map('strlen', $tests)), t('No empty tokens generated.'));
+    $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
 
     foreach ($tests as $input => $expected) {
       $output = token_replace($input, array('comment' => $comment), array('language' => $language));
-      $this->assertEqual($output, $expected, t('Sanitized comment token %token replaced.', array('%token' => $input)));
+      $this->assertEqual($output, $expected, format_string('Sanitized comment token %token replaced.', array('%token' => $input)));
     }
 
     // Generate and test unsanitized tokens.
@@ -1907,7 +1909,7 @@ class CommentTokenReplaceTestCase extends CommentHelperCase {
 
     foreach ($tests as $input => $expected) {
       $output = token_replace($input, array('comment' => $comment), array('language' => $language, 'sanitize' => FALSE));
-      $this->assertEqual($output, $expected, t('Unsanitized comment token %token replaced.', array('%token' => $input)));
+      $this->assertEqual($output, $expected, format_string('Unsanitized comment token %token replaced.', array('%token' => $input)));
     }
 
     // Load node so comment_count gets computed.
@@ -1920,7 +1922,7 @@ class CommentTokenReplaceTestCase extends CommentHelperCase {
 
     foreach ($tests as $input => $expected) {
       $output = token_replace($input, array('node' => $node), array('language' => $language));
-      $this->assertEqual($output, $expected, t('Node comment token %token replaced.', array('%token' => $input)));
+      $this->assertEqual($output, $expected, format_string('Node comment token %token replaced.', array('%token' => $input)));
     }
   }
 }
@@ -1949,25 +1951,25 @@ class CommentActionsTestCase extends CommentHelperCase {
 
     // Unpublish a comment (direct form: doesn't actually save the comment).
     comment_unpublish_action($comment);
-    $this->assertEqual($comment->status, COMMENT_NOT_PUBLISHED, t('Comment was unpublished'));
-    $this->assertWatchdogMessage('Unpublished comment %subject.', array('%subject' => $subject), t('Found watchdog message'));
+    $this->assertEqual($comment->status, COMMENT_NOT_PUBLISHED, 'Comment was unpublished');
+    $this->assertWatchdogMessage('Unpublished comment %subject.', array('%subject' => $subject), 'Found watchdog message');
     $this->clearWatchdog();
 
     // Unpublish a comment (indirect form: modify the comment in the database).
     comment_unpublish_action(NULL, array('cid' => $comment->cid));
-    $this->assertEqual(comment_load($comment->cid)->status, COMMENT_NOT_PUBLISHED, t('Comment was unpublished'));
-    $this->assertWatchdogMessage('Unpublished comment %subject.', array('%subject' => $subject), t('Found watchdog message'));
+    $this->assertEqual(comment_load($comment->cid)->status, COMMENT_NOT_PUBLISHED, 'Comment was unpublished');
+    $this->assertWatchdogMessage('Unpublished comment %subject.', array('%subject' => $subject), 'Found watchdog message');
 
     // Publish a comment (direct form: doesn't actually save the comment).
     comment_publish_action($comment);
-    $this->assertEqual($comment->status, COMMENT_PUBLISHED, t('Comment was published'));
-    $this->assertWatchdogMessage('Published comment %subject.', array('%subject' => $subject), t('Found watchdog message'));
+    $this->assertEqual($comment->status, COMMENT_PUBLISHED, 'Comment was published');
+    $this->assertWatchdogMessage('Published comment %subject.', array('%subject' => $subject), 'Found watchdog message');
     $this->clearWatchdog();
 
     // Publish a comment (indirect form: modify the comment in the database).
     comment_publish_action(NULL, array('cid' => $comment->cid));
-    $this->assertEqual(comment_load($comment->cid)->status, COMMENT_PUBLISHED, t('Comment was published'));
-    $this->assertWatchdogMessage('Published comment %subject.', array('%subject' => $subject), t('Found watchdog message'));
+    $this->assertEqual(comment_load($comment->cid)->status, COMMENT_PUBLISHED, 'Comment was published');
+    $this->assertWatchdogMessage('Published comment %subject.', array('%subject' => $subject), 'Found watchdog message');
     $this->clearWatchdog();
   }
 
@@ -1983,7 +1985,7 @@ class CommentActionsTestCase extends CommentHelperCase {
    */
   function assertWatchdogMessage($watchdog_message, $variables, $message) {
     $status = (bool) db_query_range("SELECT 1 FROM {watchdog} WHERE message = :message AND variables = :variables", 0, 1, array(':message' => $watchdog_message, ':variables' => serialize($variables)))->fetchField();
-    return $this->assert($status, $message);
+    return $this->assert($status, format_string('@message', array('@message' => $message)));
   }
 
   /**
@@ -2011,13 +2013,13 @@ class CommentFieldsTest extends CommentHelperCase {
    */
   function testCommentDefaultFields() {
     // Do not make assumptions on default node types created by the test
-    // install profile, and create our own.
+    // installation profile, and create our own.
     $this->drupalCreateContentType(array('type' => 'test_node_type'));
 
     // Check that the 'comment_body' field is present on all comment bundles.
     $instances = field_info_instances('comment');
     foreach (node_type_get_types() as $type_name => $info) {
-      $this->assertTrue(isset($instances['comment_node_' . $type_name]['comment_body']), t('The comment_body field is present for comments on type @type', array('@type' => $type_name)));
+      $this->assertTrue(isset($instances['comment_node_' . $type_name]['comment_body']), format_string('The comment_body field is present for comments on type @type', array('@type' => $type_name)));
 
       // Delete the instance along the way.
       field_delete_instance($instances['comment_node_' . $type_name]['comment_body']);
@@ -2025,7 +2027,7 @@ class CommentFieldsTest extends CommentHelperCase {
 
     // Check that the 'comment_body' field is deleted.
     $field = field_info_field('comment_body');
-    $this->assertTrue(empty($field), t('The comment_body field was deleted'));
+    $this->assertTrue(empty($field), 'The comment_body field was deleted');
 
     // Create a new content type.
     $type_name = 'test_node_type_2';
@@ -2034,9 +2036,9 @@ class CommentFieldsTest extends CommentHelperCase {
     // Check that the 'comment_body' field exists and has an instance on the
     // new comment bundle.
     $field = field_info_field('comment_body');
-    $this->assertTrue($field, t('The comment_body field exists'));
+    $this->assertTrue($field, 'The comment_body field exists');
     $instances = field_info_instances('comment');
-    $this->assertTrue(isset($instances['comment_node_' . $type_name]['comment_body']), t('The comment_body field is present for comments on type @type', array('@type' => $type_name)));
+    $this->assertTrue(isset($instances['comment_node_' . $type_name]['comment_body']), format_string('The comment_body field is present for comments on type @type', array('@type' => $type_name)));
   }
 
   /**
@@ -2052,7 +2054,7 @@ class CommentFieldsTest extends CommentHelperCase {
     $edit['modules[Core][comment][enable]'] = FALSE;
     $this->drupalPost('admin/modules', $edit, t('Save configuration'));
     $this->resetAll();
-    $this->assertFalse(module_exists('comment'), t('Comment module disabled.'));
+    $this->assertFalse(module_exists('comment'), 'Comment module disabled.');
 
     // Enable core content type modules (blog, book, and poll).
     $edit = array();
@@ -2067,7 +2069,7 @@ class CommentFieldsTest extends CommentHelperCase {
     $edit['modules[Core][comment][enable]'] = 'comment';
     $this->drupalPost('admin/modules', $edit, t('Save configuration'));
     $this->resetAll();
-    $this->assertTrue(module_exists('comment'), t('Comment module enabled.'));
+    $this->assertTrue(module_exists('comment'), 'Comment module enabled.');
 
     // Create nodes of each type.
     $blog_node = $this->drupalCreateNode(array('type' => 'blog'));

+ 2 - 0
modules/comment/comment.tpl.php

@@ -55,6 +55,8 @@
  * @see template_preprocess_comment()
  * @see template_process()
  * @see theme_comment()
+ *
+ * @ingroup themeable
  */
 ?>
 <div class="<?php print $classes; ?> clearfix"<?php print $attributes; ?>>

+ 3 - 3
modules/contact/contact.info

@@ -6,8 +6,8 @@ core = 7.x
 files[] = contact.test
 configure = admin/structure/contact
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 3 - 3
modules/contextual/contextual.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 files[] = contextual.test
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 3 - 3
modules/dashboard/dashboard.info

@@ -7,8 +7,8 @@ files[] = dashboard.test
 dependencies[] = block
 configure = admin/dashboard/customize
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 3 - 3
modules/dblog/dblog.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 files[] = dblog.test
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 1 - 1
modules/dblog/dblog.module

@@ -96,7 +96,7 @@ function dblog_init() {
 /**
  * Implements hook_cron().
  *
- * Remove expired log messages and flood control events.
+ * Remove expired log messages.
  */
 function dblog_cron() {
   // Cleanup the watchdog table.

+ 1 - 1
modules/dblog/dblog.test

@@ -256,7 +256,7 @@ class DBLogTestCase extends DrupalWebTestCase {
     // View dblog page-not-found report page.
     $this->drupalGet('admin/reports/page-not-found');
     $this->assertResponse(200);
-    // Check that full-length url displayed.
+    // Check that full-length URL displayed.
     $this->assertText($not_found_url, t('DBLog event was recorded: [page not found]'));
   }
 

+ 12 - 8
modules/field/field.api.php

@@ -690,11 +690,10 @@ function hook_field_is_empty($item, $field) {
  * which widget to use. Widget types are defined by implementing
  * hook_field_widget_info().
  *
- * Widgets are
- * @link http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html Form API @endlink
- * elements with additional processing capabilities. Widget hooks are typically
- * called by the Field Attach API during the creation of the field form
- * structure with field_attach_form().
+ * Widgets are @link forms_api_reference.html Form API @endlink elements with
+ * additional processing capabilities. Widget hooks are typically called by the
+ * Field Attach API during the creation of the field form structure with
+ * field_attach_form().
  *
  * @see field
  * @see field_types
@@ -729,6 +728,9 @@ function hook_field_is_empty($item, $field) {
  *       - FIELD_BEHAVIOR_DEFAULT: (default) If the widget accepts default
  *         values.
  *       - FIELD_BEHAVIOR_NONE: if the widget does not support default values.
+ *   - weight: (optional) An integer to determine the weight of this widget
+ *     relative to other widgets in the Field UI when selecting a widget for a
+ *     given field instance.
  *
  * @see hook_field_widget_info_alter()
  * @see hook_field_widget_form()
@@ -738,7 +740,7 @@ function hook_field_is_empty($item, $field) {
  * @see hook_field_widget_settings_form()
  */
 function hook_field_widget_info() {
-    return array(
+  return array(
     'text_textfield' => array(
       'label' => t('Text field'),
       'field types' => array('text'),
@@ -765,6 +767,8 @@ function hook_field_widget_info() {
         'multiple values' => FIELD_BEHAVIOR_DEFAULT,
         'default value' => FIELD_BEHAVIOR_DEFAULT,
       ),
+      // As an advanced widget, force it to sink to the bottom of the choices.
+      'weight' => 2,
     ),
   );
 }
@@ -1072,8 +1076,8 @@ function hook_field_formatter_info() {
  * Perform alterations on Field API formatter types.
  *
  * @param $info
- *   Array of informations on formatter types exposed by
- *   hook_field_field_formatter_info() implementations.
+ *   An array of information on formatter types exposed by
+ *   hook_field_formatter_info() implementations.
  */
 function hook_field_formatter_info_alter(&$info) {
   // Add a setting to a formatter type.

+ 33 - 2
modules/field/field.form.inc

@@ -6,7 +6,38 @@
  */
 
 /**
- * Create a separate form element for each field.
+ * Creates a form element for a field and can populate it with a default value.
+ *
+ * If the form element is not associated with an entity (i.e., $entity is NULL)
+ * field_get_default_value will be called to supply the default value for the
+ * field. Also allows other modules to alter the form element by implementing
+ * their own hooks.
+ *
+ * @param $entity_type
+ *   The type of entity (for example 'node' or 'user') that the field belongs
+ *   to.
+ * @param $entity
+ *   The entity object that the field belongs to. This may be NULL if creating a
+ *   form element with a default value.
+ * @param $field
+ *   An array representing the field whose editing element is being created.
+ * @param $instance
+ *   An array representing the structure for $field in its current context.
+ * @param $langcode
+ *   The language associated with the field.
+ * @param $items
+ *   An array of the field values. When creating a new entity this may be NULL
+ *   or an empty array to use default values.
+ * @param $form
+ *   An array representing the form that the editing element will be attached
+ *   to. 
+ * @param $form_state
+ *   An array containing the current state of the form.
+ * @param $get_delta
+ *   Used to get only a specific delta value of a multiple value field.
+ *
+ * @return
+ *  The form element array created for this field.
  */
 function field_default_form($entity_type, $entity, $field, $instance, $langcode, $items, &$form, &$form_state, $get_delta = NULL) {
   // This could be called with no entity, as when a UI module creates a
@@ -278,7 +309,7 @@ function theme_field_multiple_value_form($variables) {
 
     $header = array(
       array(
-        'data' => '<label>' . t('!title: !required', array('!title' => $element['#title'], '!required' => $required)) . "</label>",
+        'data' => '<label>' . t('!title !required', array('!title' => $element['#title'], '!required' => $required)) . "</label>",
         'colspan' => 2,
         'class' => array('field-label'),
       ),

+ 3 - 3
modules/field/field.info

@@ -10,8 +10,8 @@ dependencies[] = field_sql_storage
 required = TRUE
 stylesheets[all][] = theme/field.css
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 7 - 2
modules/field/field.info.inc

@@ -54,8 +54,8 @@ function field_info_cache_clear() {
  *     the field type.
  *   - 'widget types': Array of hook_field_widget_info() results, keyed by
  *     widget_type. Each element has the following components: label, field
- *     types, settings, and behaviors from hook_field_widget_info(), as well
- *     as module, giving the module that exposes the widget type.
+ *     types, settings, weight, and behaviors from hook_field_widget_info(),
+ *     as well as module, giving the module that exposes the widget type.
  *   - 'formatter types': Array of hook_field_formatter_info() results, keyed by
  *     formatter_type. Each element has the following components: label, field
  *     types, and behaviors from hook_field_formatter_info(), as well as
@@ -124,6 +124,7 @@ function _field_info_collate_types($reset = FALSE) {
         }
       }
       drupal_alter('field_widget_info', $info['widget types']);
+      uasort($info['widget types'], 'drupal_sort_weight');
 
       // Populate formatter types.
       foreach (module_implements('field_formatter_info') as $module) {
@@ -702,6 +703,10 @@ function field_info_instances($entity_type = NULL, $bundle_name = NULL) {
  *   The field name for the instance.
  * @param $bundle_name
  *   The bundle name for the instance.
+ *
+ * @return
+ *   An associative array of instance data for the specific field and bundle;
+ *   NULL if the instance does not exist.
  */
 function field_info_instance($entity_type, $field_name, $bundle_name) {
   $info = _field_info_collate_fields();

+ 6 - 4
modules/field/field.install

@@ -172,7 +172,7 @@ function field_schema() {
  * This function can be used for databases whose schema is at field module
  * version 7000 or higher.
  *
- * @ingroup update-api-6.x-to-7.x
+ * @ingroup update_api
  */
 function _update_7000_field_create_field(&$field) {
   // Merge in default values.`
@@ -253,7 +253,7 @@ function _update_7000_field_create_field(&$field) {
  * @param $field_name
  *   The field name to delete.
  *
- * @ingroup update-api-6.x-to-7.x
+ * @ingroup update_api
  */
 function _update_7000_field_delete_field($field_name) {
   $table_name = 'field_data_' . $field_name;
@@ -284,7 +284,7 @@ function _update_7000_field_delete_field($field_name) {
  *
  * This function is valid for a database schema version 7000.
  *
- * @ingroup update-api-6.x-to-7.x
+ * @ingroup update_api
  */
 function _update_7000_field_delete_instance($field_name, $entity_type, $bundle) {
   // Delete field instance configuration data.
@@ -322,6 +322,8 @@ function _update_7000_field_delete_instance($field_name, $entity_type, $bundle)
  * @return
  *   An array of fields matching $conditions, keyed by the property specified
  *   by the $key parameter.
+ *
+ * @ingroup update_api
  */
 function _update_7000_field_read_fields(array $conditions = array(), $key = 'id') {
   $fields = array();
@@ -356,7 +358,7 @@ function _update_7000_field_read_fields(array $conditions = array(), $key = 'id'
  * This function can be used for databases whose schema is at field module
  * version 7000 or higher.
  *
- * @ingroup update-api-6.x-to-7.x
+ * @ingroup update_api
  */
 function _update_7000_field_create_instance($field, &$instance) {
   // Merge in defaults.

+ 1 - 1
modules/field/field.module

@@ -376,7 +376,7 @@ function field_system_info_alter(&$info, $file, $type) {
       }
       if ($non_deleted) {
         if (module_exists('field_ui')) {
-          $explanation = t('Field type(s) in use - see !link', array('!link' => l(t('Field list'), 'admin/reports/fields')));
+          $explanation = t('Field type(s) in use - see <a href="@fields-page">Field list</a>', array('@fields-page' => url('admin/reports/fields')));
         }
         else {
           $explanation = t('Fields type(s) in use');

+ 3 - 3
modules/field/modules/field_sql_storage/field_sql_storage.info

@@ -7,8 +7,8 @@ dependencies[] = field
 files[] = field_sql_storage.test
 required = TRUE
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 1 - 1
modules/field/modules/field_sql_storage/field_sql_storage.install

@@ -30,7 +30,7 @@ function field_sql_storage_schema() {
  * This function can be used for databases whose schema is at field module
  * version 7000 or higher.
  *
- * @ingroup update-api-6.x-to-7.x
+ * @ingroup update_api
  */
 function _update_7000_field_sql_storage_write($entity_type, $bundle, $entity_id, $revision_id, $field_name, $data) {
   $table_name = "field_data_{$field_name}";

+ 3 - 3
modules/field/modules/list/list.info

@@ -7,8 +7,8 @@ dependencies[] = field
 dependencies[] = options
 files[] = tests/list.test
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 3 - 3
modules/field/modules/list/tests/list_test.info

@@ -5,8 +5,8 @@ package = Testing
 version = VERSION
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 3 - 3
modules/field/modules/number/number.info

@@ -6,8 +6,8 @@ core = 7.x
 dependencies[] = field
 files[] = number.test
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 3 - 3
modules/field/modules/options/options.info

@@ -6,8 +6,8 @@ core = 7.x
 dependencies[] = field
 files[] = options.test
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 3 - 3
modules/field/modules/text/text.info

@@ -7,8 +7,8 @@ dependencies[] = field
 files[] = text.test
 required = TRUE
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 4 - 1
modules/field/tests/field.test

@@ -1119,8 +1119,11 @@ class FieldInfoTestCase extends FieldTestCase {
           'test_setting' => 999)));
     field_create_instance($instance);
 
+    $info = entity_get_info('test_entity');
     $instances = field_info_instances('test_entity', $instance['bundle']);
-    $this->assertEqual(count($instances), 1, t('One instance shows up in info when attached to a bundle.'));
+    $this->assertEqual(count($instances), 1, format_string('One instance shows up in info when attached to a bundle on a @label.', array(
+      '@label' => $info['label']
+    )));
     $this->assertTrue($instance < $instances[$instance['field_name']], t('Instance appears in info correctly'));
 
     // Test a valid entity type but an invalid bundle.

+ 7 - 7
modules/field/tests/field_test.entity.inc

@@ -23,7 +23,7 @@ function field_test_entity_info() {
 
   return array(
     'test_entity' => array(
-      'name' => t('Test Entity'),
+      'label' => t('Test Entity'),
       'fieldable' => TRUE,
       'field cache' => FALSE,
       'base table' => 'test_entity',
@@ -38,7 +38,7 @@ function field_test_entity_info() {
     ),
     // This entity type doesn't get form handling for now...
     'test_cacheable_entity' => array(
-      'name' => t('Test Entity, cacheable'),
+      'label' => t('Test Entity, cacheable'),
       'fieldable' => TRUE,
       'field cache' => TRUE,
       'entity keys' => array(
@@ -50,7 +50,7 @@ function field_test_entity_info() {
       'view modes' => $test_entity_modes,
     ),
     'test_entity_bundle_key' => array(
-      'name' => t('Test Entity with a bundle key.'),
+      'label' => t('Test Entity with a bundle key.'),
       'base table' => 'test_entity_bundle_key',
       'fieldable' => TRUE,
       'field cache' => FALSE,
@@ -63,7 +63,7 @@ function field_test_entity_info() {
     ),
     // In this case, the bundle key is not stored in the database.
     'test_entity_bundle' => array(
-      'name' => t('Test Entity with a specified bundle.'),
+      'label' => t('Test Entity with a specified bundle.'),
       'base table' => 'test_entity_bundle',
       'fieldable' => TRUE,
       'controller class' => 'TestEntityBundleController',
@@ -77,7 +77,7 @@ function field_test_entity_info() {
     ),
     // @see EntityPropertiesTestCase::testEntityLabel()
     'test_entity_no_label' => array(
-      'name' => t('Test entity without label'),
+      'label' => t('Test entity without label'),
       'fieldable' => TRUE,
       'field cache' => FALSE,
       'base table' => 'test_entity',
@@ -90,7 +90,7 @@ function field_test_entity_info() {
       'view modes' => $test_entity_modes,
     ),
     'test_entity_label' => array(
-      'name' => t('Test entity label'),
+      'label' => t('Test entity label'),
       'fieldable' => TRUE,
       'field cache' => FALSE,
       'base table' => 'test_entity',
@@ -104,7 +104,7 @@ function field_test_entity_info() {
       'view modes' => $test_entity_modes,
     ),
     'test_entity_label_callback' => array(
-      'name' => t('Test entity label callback'),
+      'label' => t('Test entity label callback'),
       'fieldable' => TRUE,
       'field cache' => FALSE,
       'base table' => 'test_entity',

+ 3 - 3
modules/field/tests/field_test.info

@@ -6,8 +6,8 @@ files[] = field_test.entity.inc
 version = VERSION
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 2 - 0
modules/field/theme/field.tpl.php

@@ -40,6 +40,8 @@
  *
  * @see template_preprocess_field()
  * @see theme_field()
+ *
+ * @ingroup themeable
  */
 ?>
 <!--

+ 3 - 3
modules/field_ui/field_ui.info

@@ -6,8 +6,8 @@ core = 7.x
 dependencies[] = field
 files[] = field_ui.test
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 0 - 6
modules/file/file.api.php

@@ -51,12 +51,6 @@ function hook_file_download_access($file_item, $entity_type, $entity) {
  *   The type of $entity; for example, 'node' or 'user'.
  * @param $entity
  *   The $entity to which $file is referenced.
- *
- * @return
- *   An array of grants, keyed by module name, each with a Boolean grant value.
- *   Return an empty array to assert FALSE. You may choose to return your own
- *   module's value in addition to other grants or to overwrite the values set
- *   by other modules.
  */
 function hook_file_download_access_alter(&$grants, $file_item, $entity_type, $entity) {
   // For our example module, we always enforce the rules set by node module.

+ 3 - 3
modules/file/file.info

@@ -6,8 +6,8 @@ core = 7.x
 dependencies[] = field
 files[] = tests/file.test
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 8 - 1
modules/file/file.js

@@ -73,7 +73,14 @@ Drupal.file = Drupal.file || {
       var acceptableMatch = new RegExp('\\.(' + extensionPattern + ')$', 'gi');
       if (!acceptableMatch.test(this.value)) {
         var error = Drupal.t("The selected file %filename cannot be uploaded. Only files with the following extensions are allowed: %extensions.", {
-          '%filename': this.value,
+          // According to the specifications of HTML5, a file upload control
+          // should not reveal the real local path to the file that a user
+          // has selected. Some web browsers implement this restriction by
+          // replacing the local path with "C:\fakepath\", which can cause
+          // confusion by leaving the user thinking perhaps Drupal could not
+          // find the file because it messed up the file path. To avoid this
+          // confusion, therefore, we strip out the bogus fakepath string.
+          '%filename': this.value.replace('C:\\fakepath\\', ''),
           '%extensions': extensionPattern.replace(/\|/g, ', ')
         });
         $(this).closest('div.form-managed-file').prepend('<div class="messages error file-upload-js-error">' + error + '</div>');

+ 3 - 3
modules/file/tests/file_module_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 3 - 3
modules/filter/filter.info

@@ -7,8 +7,8 @@ files[] = filter.test
 required = TRUE
 configure = admin/config/content/formats
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 3 - 3
modules/forum/forum.info

@@ -9,8 +9,8 @@ files[] = forum.test
 configure = admin/structure/forum
 stylesheets[all][] = forum.css
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 7 - 5
modules/forum/forum.module

@@ -330,10 +330,12 @@ function forum_node_presave($node) {
     $langcode = key($node->taxonomy_forums);
     if (!empty($node->taxonomy_forums[$langcode])) {
       $node->forum_tid = $node->taxonomy_forums[$langcode][0]['tid'];
-      $old_tid = db_query_range("SELECT f.tid FROM {forum} f INNER JOIN {node} n ON f.vid = n.vid WHERE n.nid = :nid ORDER BY f.vid DESC", 0, 1, array(':nid' => $node->nid))->fetchField();
-      if ($old_tid && isset($node->forum_tid) && ($node->forum_tid != $old_tid) && !empty($node->shadow)) {
-        // A shadow copy needs to be created. Retain new term and add old term.
-        $node->taxonomy_forums[$langcode][] = array('tid' => $old_tid);
+      if (isset($node->nid)) {
+        $old_tid = db_query_range("SELECT f.tid FROM {forum} f INNER JOIN {node} n ON f.vid = n.vid WHERE n.nid = :nid ORDER BY f.vid DESC", 0, 1, array(':nid' => $node->nid))->fetchField();
+        if ($old_tid && isset($node->forum_tid) && ($node->forum_tid != $old_tid) && !empty($node->shadow)) {
+          // A shadow copy needs to be created. Retain new term and add old term.
+          $node->taxonomy_forums[$langcode][] = array('tid' => $old_tid);
+        }
       }
     }
   }
@@ -1328,7 +1330,7 @@ function _forum_get_topic_order($sortby) {
  *   The ID of the node to update.
  */
 function _forum_update_forum_index($nid) {
-  $count = db_query('SELECT COUNT(cid) FROM {comment} WHERE nid = :nid AND status = :status', array(
+  $count = db_query('SELECT COUNT(cid) FROM {comment} c INNER JOIN {forum_index} i ON c.nid = i.nid WHERE c.nid = :nid AND c.status = :status', array(
     ':nid' => $nid,
     ':status' => COMMENT_PUBLISHED,
   ))->fetchField();

+ 8 - 0
modules/forum/forum.test

@@ -197,6 +197,14 @@ class ForumTestCase extends DrupalWebTestCase {
     $this->drupalGet('forum/' . $this->forum['tid']);
     $this->drupalPost("node/$node->nid/edit", array(), t('Save'));
     $this->assertResponse(200);
+
+    // Make sure constructing a forum node programmatically produces no notices.
+    $node = new stdClass;
+    $node->type = 'forum';
+    $node->title = 'Test forum notices';
+    $node->uid = 1;
+    $node->taxonomy_forums[LANGUAGE_NONE][0]['tid'] = $this->root_forum['tid'];
+    node_save($node);
   }
 
   /**

+ 3 - 3
modules/help/help.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 files[] = help.test
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 9 - 4
modules/image/image.field.inc

@@ -600,9 +600,12 @@ function theme_image_formatter($variables) {
   $item = $variables['item'];
   $image = array(
     'path' => $item['uri'],
-    'alt' => $item['alt'],
   );
 
+  if (array_key_exists('alt', $item)) {
+    $image['alt'] = $item['alt'];
+  }
+
   if (isset($item['attributes'])) {
     $image['attributes'] = $item['attributes'];
   }
@@ -613,7 +616,7 @@ function theme_image_formatter($variables) {
   }
 
   // Do not output an empty 'title' attribute.
-  if (drupal_strlen($item['title']) > 0) {
+  if (isset($item['title']) && drupal_strlen($item['title']) > 0) {
     $image['title'] = $item['title'];
   }
 
@@ -625,9 +628,11 @@ function theme_image_formatter($variables) {
     $output = theme('image', $image);
   }
 
-  if (!empty($variables['path']['path'])) {
+  // The link path and link options are both optional, but for the options to be
+  // processed, the link path must at least be an empty string.
+  if (isset($variables['path']['path'])) {
     $path = $variables['path']['path'];
-    $options = $variables['path']['options'];
+    $options = isset($variables['path']['options']) ? $variables['path']['options'] : array();
     // When displaying an image inside a link, the html option must be TRUE.
     $options['html'] = TRUE;
     $output = l($output, $path, $options);

+ 3 - 3
modules/image/image.info

@@ -7,8 +7,8 @@ dependencies[] = file
 files[] = image.test
 configure = admin/config/media/image-styles
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 3 - 3
modules/image/image.module

@@ -34,7 +34,7 @@ define('IMAGE_STORAGE_MODULE', IMAGE_STORAGE_OVERRIDE | IMAGE_STORAGE_DEFAULT);
 require_once DRUPAL_ROOT . '/modules/image/image.field.inc';
 
 /**
- * Implement of hook_help().
+ * Implements hook_help().
  */
 function image_help($path, $arg) {
   switch ($path) {
@@ -1054,7 +1054,7 @@ function image_effect_definitions() {
   $effects = &drupal_static(__FUNCTION__);
 
   if (!isset($effects)) {
-    if ($cache = cache_get("image_effects:$langcode") && !empty($cache->data)) {
+    if ($cache = cache_get("image_effects:$langcode")) {
       $effects = $cache->data;
     }
     else {
@@ -1262,7 +1262,7 @@ function theme_image_style($variables) {
   $variables['width'] = $dimensions['width'];
   $variables['height'] = $dimensions['height'];
 
-  // Determine the url for the styled image.
+  // Determine the URL for the styled image.
   $variables['path'] = image_style_url($variables['style_name'], $variables['path']);
   return theme('image', $variables);
 }

+ 99 - 7
modules/image/image.test

@@ -183,7 +183,7 @@ class ImageStylesPathAndUrlTestCase extends DrupalWebTestCase {
 
     // Create a working copy of the file.
     $files = $this->drupalGetTestFiles('image');
-    $file = reset($files);
+    $file = array_shift($files);
     $image_info = image_get_info($file->uri);
     $original_uri = file_unmanaged_copy($file->uri, $scheme . '://', FILE_EXISTS_RENAME);
     // Let the image_module_test module know about this file, so it can claim
@@ -212,18 +212,30 @@ class ImageStylesPathAndUrlTestCase extends DrupalWebTestCase {
       $this->assertEqual($this->drupalGetHeader('Expires'), 'Sun, 19 Nov 1978 05:00:00 GMT', t('Expires header was sent.'));
       $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'no-cache, must-revalidate, post-check=0, pre-check=0', t('Cache-Control header was set to prevent caching.'));
       $this->assertEqual($this->drupalGetHeader('X-Image-Owned-By'), 'image_module_test', t('Expected custom header has been added.'));
-      // Verify access is denied to private image styles.
-      $this->drupalLogout();
+
+      // Make sure that a second request to the already existing derivate works
+      // too.
       $this->drupalGet($generate_url);
+      $this->assertResponse(200, t('Image was generated at the URL.'));
+
+      // Repeat this with a different file that we do not have access to and
+      // make sure that access is denied.
+      $file_noaccess = array_shift($files);
+      $original_uri_noaccess = file_unmanaged_copy($file_noaccess->uri, $scheme . '://', FILE_EXISTS_RENAME);
+      $generated_uri_noaccess = $scheme . '://styles/' . $this->style_name . '/' . $scheme . '/'. drupal_basename($original_uri_noaccess);
+      $this->assertFalse(file_exists($generated_uri_noaccess), t('Generated file does not exist.'));
+      $generate_url_noaccess = image_style_url($this->style_name, $original_uri_noaccess);
+
+      $this->drupalGet($generate_url_noaccess);
       $this->assertResponse(403, t('Confirmed that access is denied for the private image style.') );
       // Verify that images are not appended to the response. Currently this test only uses PNG images.
       if (strpos($generate_url, '.png') === FALSE ) {
-        $this->fail( t('Confirming that private image styles are not appended require PNG file.') );
+        $this->fail('Confirming that private image styles are not appended require PNG file.');
       }
       else {
         // Check for PNG-Signature (cf. http://www.libpng.org/pub/png/book/chapter08.html#png.ch08.div.2) in the
         // response body.
-        $this->assertNoRaw( chr(137) . chr(80) . chr(78) . chr(71) . chr(13) . chr(10) . chr(26) . chr(10), t('No PNG signature found in the response body.') );
+        $this->assertNoRaw( chr(137) . chr(80) . chr(78) . chr(71) . chr(13) . chr(10) . chr(26) . chr(10), 'No PNG signature found in the response body.');
       }
     }
   }
@@ -243,7 +255,7 @@ class ImageEffectsUnitTest extends ImageToolkitTestCase {
   }
 
   function setUp() {
-    parent::setUp('image_test');
+    parent::setUp('image_module_test');
     module_load_include('inc', 'image', 'image.effects');
   }
 
@@ -330,6 +342,25 @@ class ImageEffectsUnitTest extends ImageToolkitTestCase {
     $this->assertEqual($calls['rotate'][0][1], 90, t('Degrees were passed correctly'));
     $this->assertEqual($calls['rotate'][0][2], 0xffffff, t('Background color was passed correctly'));
   }
+
+  /**
+   * Test image effect caching.
+   */
+  function testImageEffectsCaching() {
+    $image_effect_definitions_called = &drupal_static('image_module_test_image_effect_info_alter');
+
+    // First call should grab a fresh copy of the data.
+    $effects = image_effect_definitions();
+    $this->assertTrue($image_effect_definitions_called === 1, 'image_effect_definitions() generated data.');
+
+    // Second call should come from cache.
+    drupal_static_reset('image_effect_definitions');
+    drupal_static_reset('image_module_test_image_effect_info_alter');
+    $cached_effects = image_effect_definitions();
+    $this->assertTrue(is_null($image_effect_definitions_called), 'image_effect_definitions() returned data from cache.');
+
+    $this->assertTrue($effects == $cached_effects, 'Cached effects are the same as generated effects.');
+  }
 }
 
 /**
@@ -717,7 +748,7 @@ class ImageFieldDisplayTestCase extends ImageFieldTestCase {
     if ($scheme == 'private') {
       // Only verify HTTP headers when using private scheme and the headers are
       // sent by Drupal.
-      $this->assertEqual($this->drupalGetHeader('Content-Type'), 'image/png; name="' . $test_image->filename . '"', t('Content-Type header was sent.'));
+      $this->assertEqual($this->drupalGetHeader('Content-Type'), 'image/png', t('Content-Type header was sent.'));
       $this->assertEqual($this->drupalGetHeader('Content-Disposition'), 'inline; filename="' . $test_image->filename . '"', t('Content-Disposition header was sent.'));
       $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'private', t('Cache-Control header was sent.'));
 
@@ -1566,3 +1597,64 @@ class ImageFieldDefaultImagesTestCase extends ImageFieldTestCase {
   }
 
 }
+
+/**
+ * Tests image theme functions.
+ */
+class ImageThemeFunctionWebTestCase extends DrupalWebTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Image theme functions',
+      'description' => 'Test that the image theme functions work correctly.',
+      'group' => 'Image',
+    );
+  }
+
+  function setUp() {
+    parent::setUp(array('image'));
+  }
+
+  /**
+   * Tests usage of the image field formatters.
+   */
+  function testImageFormatterTheme() {
+    // Create an image.
+    $files = $this->drupalGetTestFiles('image');
+    $file = reset($files);
+    $original_uri = file_unmanaged_copy($file->uri, 'public://', FILE_EXISTS_RENAME);
+
+    // Create a style.
+    image_style_save(array('name' => 'test'));
+    $url = image_style_url('test', $original_uri);
+
+    // Test using theme_image_formatter() without an image title, alt text, or
+    // link options.
+    $path = $this->randomName();
+    $element = array(
+      '#theme' => 'image_formatter',
+      '#image_style' => 'test',
+      '#item' => array(
+        'uri' => $original_uri,
+      ),
+      '#path' => array(
+        'path' => $path,
+      ),
+    );
+    $rendered_element = render($element);
+    $expected_result = '<a href="' . url($path) . '"><img typeof="foaf:Image" src="' . $url . '" alt="" /></a>';
+    $this->assertEqual($expected_result, $rendered_element, 'theme_image_formatter() correctly renders without title, alt, or path options.');
+
+    // Link the image to a fragment on the page, and not a full URL.
+    $fragment = $this->randomName();
+    $element['#path']['path'] = '';
+    $element['#path']['options'] = array(
+      'external' => TRUE,
+      'fragment' => $fragment,
+    );
+    $rendered_element = render($element);
+    $expected_result = '<a href="#' . $fragment . '"><img typeof="foaf:Image" src="' . $url . '" alt="" /></a>';
+    $this->assertEqual($expected_result, $rendered_element, 'theme_image_formatter() correctly renders a link fragment.');
+  }
+
+}

+ 3 - 3
modules/image/tests/image_module_test.info

@@ -6,8 +6,8 @@ core = 7.x
 files[] = image_module_test.module
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 10 - 1
modules/image/tests/image_module_test.module

@@ -9,7 +9,6 @@ function image_module_test_file_download($uri) {
   if (variable_get('image_module_test_file_download', FALSE) == $uri) {
     return array('X-Image-Owned-By' => 'image_module_test');
   }
-  return -1;
 }
 
 /**
@@ -39,3 +38,13 @@ function image_module_test_image_effect_info() {
 function image_module_test_null_effect(array &$image, array $data) {
   return TRUE;
 }
+
+/**
+ * Implements hook_image_effect_info_alter().
+ *
+ * Used to keep a count of cache misses in image_effect_definitions().
+ */
+function image_module_test_image_effect_info_alter(&$effects) {
+  $image_effects_definition_called = &drupal_static(__FUNCTION__, 0);
+  $image_effects_definition_called++;
+}

+ 3 - 3
modules/locale/locale.info

@@ -6,8 +6,8 @@ core = 7.x
 files[] = locale.test
 configure = admin/config/regional/language
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

+ 14 - 1
modules/locale/locale.install

@@ -201,6 +201,19 @@ function locale_update_7004() {
   }
 }
 
+/**
+ * Increase {locales_languages}.formula column's length.
+ */
+function locale_update_7005() {
+  db_change_field('languages', 'formula', 'formula', array(
+    'type' => 'varchar',
+    'length' => 255,
+    'not null' => TRUE,
+    'default' => '',
+    'description' => 'Plural formula in PHP code to evaluate to get plural indexes.',
+  ));
+}
+
 /**
  * @} End of "addtogroup updates-7.x-extra".
  */
@@ -303,7 +316,7 @@ function locale_schema() {
       ),
       'formula' => array(
         'type' => 'varchar',
-        'length' => 128,
+        'length' => 255,
         'not null' => TRUE,
         'default' => '',
         'description' => 'Plural formula in PHP code to evaluate to get plural indexes.',

+ 1 - 1
modules/locale/locale.module

@@ -1033,7 +1033,7 @@ function locale_url_outbound_alter(&$path, &$options, $original_path) {
       include_once DRUPAL_ROOT . '/includes/language.inc';
 
       foreach (language_types_configurable() as $type) {
-        // Get url rewriter callbacks only from enabled language providers.
+        // Get URL rewriter callbacks only from enabled language providers.
         $negotiation = variable_get("language_negotiation_$type", array());
 
         foreach ($negotiation as $id => $provider) {

+ 6 - 6
modules/locale/locale.test

@@ -1958,7 +1958,7 @@ class LocalePathFunctionalTest extends DrupalWebTestCase {
   public static function getInfo() {
     return array(
       'name' => 'Path language settings',
-      'description' => 'Checks you can configure a language for individual url aliases.',
+      'description' => 'Checks you can configure a language for individual URL aliases.',
       'group' => 'Locale',
     );
   }
@@ -2268,7 +2268,7 @@ class LocaleUILanguageNegotiationTest extends DrupalWebTestCase {
   public static function getInfo() {
     return array(
       'name' => 'UI language negotiation',
-      'description' => 'Test UI language switching by url path prefix and domain.',
+      'description' => 'Test UI language switching by URL path prefix and domain.',
       'group' => 'Locale',
     );
   }
@@ -2396,7 +2396,7 @@ class LocaleUILanguageNegotiationTest extends DrupalWebTestCase {
     $this->assertResponse(404, "Unknown language path prefix should return 404");
 
     // Setup for domain negotiation, first configure the language to have domain
-    // URL. We use https and a port to make sure that only the domain name is used.
+    // URL. We use HTTPS and a port to make sure that only the domain name is used.
     $edit = array('prefix' => '', 'domain' => "https://$language_domain:99");
     $this->drupalPost("admin/config/regional/language/edit/$language", $edit, t('Save language'));
     // Set the site to use domain language negotiation.
@@ -2513,7 +2513,7 @@ class LocaleUILanguageNegotiationTest extends DrupalWebTestCase {
     $languages = language_list();
 
     foreach (array('it', 'fr') as $langcode) {
-      // Build the link we're going to test based on the clean url setting.
+      // Build the link we're going to test based on the clean URL setting.
       $link = (!empty($GLOBALS['conf']['clean_url'])) ? $langcode . '.example.com/admin' : $langcode . '.example.com/?q=admin';
 
       // Test URL in another language.
@@ -2524,14 +2524,14 @@ class LocaleUILanguageNegotiationTest extends DrupalWebTestCase {
       $correct_link = $url_scheme . $link;
       $this->assertTrue($url == $correct_link, t('The url() function returns the right url (@url) in accordance with the chosen language', array('@url' => $url . " == " . $correct_link)));
 
-      // Test https via options.
+      // Test HTTPS via options.
       variable_set('https', TRUE);
       $url = url('admin', array('https' => TRUE, 'language' => $languages[$langcode]));
       $correct_link = 'https://' . $link;
       $this->assertTrue($url == $correct_link, t('The url() function returns the right https url (via options) (@url) in accordance with the chosen language', array('@url' => $url . " == " . $correct_link)));
       variable_set('https', FALSE);
 
-      // Test https via current url scheme.
+      // Test HTTPS via current URL scheme.
       $temp_https = $is_https;
       $is_https = TRUE;
       $url = url('admin', array('language' => $languages[$langcode]));

+ 3 - 3
modules/locale/tests/locale_test.info

@@ -5,8 +5,8 @@ package = Testing
 version = VERSION
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2012-10-17
-version = "7.16"
+; Information added by drupal.org packaging script on 2012-11-07
+version = "7.17"
 project = "drupal"
-datestamp = "1350508567"
+datestamp = "1352325357"
 

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