Browse Source

security update for uuid xmlsitemap file_field_path

Bachir Soussi Chiadmi 5 years ago
parent
commit
a163542966
100 changed files with 5266 additions and 1914 deletions
  1. 121 0
      sites/all/modules/filefield_paths/.travis.yml
  2. 100 1
      sites/all/modules/filefield_paths/CHANGELOG.txt
  3. 47 34
      sites/all/modules/filefield_paths/README.md
  4. 49 0
      sites/all/modules/filefield_paths/filefield_paths.admin.inc
  5. 71 0
      sites/all/modules/filefield_paths/filefield_paths.api.php
  6. 29 14
      sites/all/modules/filefield_paths/filefield_paths.drush.inc
  7. 18 15
      sites/all/modules/filefield_paths/filefield_paths.info
  8. 58 35
      sites/all/modules/filefield_paths/filefield_paths.install
  9. 430 133
      sites/all/modules/filefield_paths/filefield_paths.module
  10. 72 0
      sites/all/modules/filefield_paths/filefield_paths.tokens.inc
  11. 57 0
      sites/all/modules/filefield_paths/filefield_paths.variable.inc
  12. 18 2
      sites/all/modules/filefield_paths/modules/features.inc
  13. 4 1
      sites/all/modules/filefield_paths/modules/file.inc
  14. 91 42
      sites/all/modules/filefield_paths/modules/filefield_paths.inc
  15. 17 0
      sites/all/modules/filefield_paths/modules/image.inc
  16. 0 63
      sites/all/modules/filefield_paths/modules/token.inc
  17. 3 0
      sites/all/modules/filefield_paths/modules/video.inc
  18. 327 0
      sites/all/modules/filefield_paths/tests/filefield_paths.general.test
  19. 90 0
      sites/all/modules/filefield_paths/tests/filefield_paths.test
  20. 104 0
      sites/all/modules/filefield_paths/tests/filefield_paths.text_replace.test
  21. 103 0
      sites/all/modules/filefield_paths/tests/filefield_paths.tokens.test
  22. 81 0
      sites/all/modules/filefield_paths/tests/filefield_paths.update.test
  23. 12 0
      sites/all/modules/filefield_paths/tests/filefield_paths_test.info
  24. 16 0
      sites/all/modules/filefield_paths/tests/filefield_paths_test.module
  25. 84 0
      sites/all/modules/filefield_paths/tests/pathauto.test
  26. 90 0
      sites/all/modules/filefield_paths/tests/redirect.test
  27. 82 0
      sites/all/modules/filefield_paths/tests/transliteration.test
  28. 74 0
      sites/all/modules/uuid/.travis.yml
  29. 1 0
      sites/all/modules/uuid/README.txt
  30. 17 2
      sites/all/modules/uuid/plugins/arguments/entity_uuid.inc
  31. 2 0
      sites/all/modules/uuid/uuid.admin.inc
  32. 13 39
      sites/all/modules/uuid/uuid.api.php
  33. 134 98
      sites/all/modules/uuid/uuid.core.inc
  34. 2 2
      sites/all/modules/uuid/uuid.drush.inc
  35. 132 38
      sites/all/modules/uuid/uuid.entity.inc
  36. 17 5
      sites/all/modules/uuid/uuid.features.inc
  37. 112 41
      sites/all/modules/uuid/uuid.inc
  38. 5 4
      sites/all/modules/uuid/uuid.info
  39. 83 22
      sites/all/modules/uuid/uuid.install
  40. 24 21
      sites/all/modules/uuid/uuid.module
  41. 303 287
      sites/all/modules/uuid/uuid.test
  42. 14 0
      sites/all/modules/uuid/uuid.tokens.inc
  43. 2 1
      sites/all/modules/uuid/uuid.views.inc
  44. 0 402
      sites/all/modules/uuid/uuid_default_entities_example/uuid_default_entities_example.features.uuid_entities.inc
  45. 0 15
      sites/all/modules/uuid/uuid_default_entities_example/uuid_default_entities_example.info
  46. 0 6
      sites/all/modules/uuid/uuid_default_entities_example/uuid_default_entities_example.module
  47. 3 4
      sites/all/modules/uuid/uuid_path/uuid_path.info
  48. 7 8
      sites/all/modules/uuid/uuid_path/uuid_path.module
  49. 0 12
      sites/all/modules/uuid/uuid_services/resources/field_collection.resource.inc
  50. 30 0
      sites/all/modules/uuid/uuid_services/uuid_services.admin.inc
  51. 150 0
      sites/all/modules/uuid/uuid_services/uuid_services.file_services.test
  52. 9 4
      sites/all/modules/uuid/uuid_services/uuid_services.info
  53. 14 0
      sites/all/modules/uuid/uuid_services/uuid_services.install
  54. 60 24
      sites/all/modules/uuid/uuid_services/uuid_services.module
  55. 1 0
      sites/all/modules/uuid/uuid_services_example/uuid_services_example.features.inc
  56. 15 14
      sites/all/modules/uuid/uuid_services_example/uuid_services_example.info
  57. 2 1
      sites/all/modules/uuid/uuid_services_example/uuid_services_example.module
  58. 21 9
      sites/all/modules/uuid/uuid_services_example/uuid_services_example.services.inc
  59. 43 18
      sites/all/modules/xmlsitemap/README.txt
  60. 91 55
      sites/all/modules/xmlsitemap/xmlsitemap.admin.inc
  61. 43 13
      sites/all/modules/xmlsitemap/xmlsitemap.api.php
  62. 14 4
      sites/all/modules/xmlsitemap/xmlsitemap.drush.inc
  63. 57 24
      sites/all/modules/xmlsitemap/xmlsitemap.generate.inc
  64. 5 5
      sites/all/modules/xmlsitemap/xmlsitemap.inc
  65. 4 11
      sites/all/modules/xmlsitemap/xmlsitemap.info
  66. 24 8
      sites/all/modules/xmlsitemap/xmlsitemap.install
  67. 217 83
      sites/all/modules/xmlsitemap/xmlsitemap.module
  68. 6 4
      sites/all/modules/xmlsitemap/xmlsitemap.pages.inc
  69. 262 83
      sites/all/modules/xmlsitemap/xmlsitemap.test
  70. 97 14
      sites/all/modules/xmlsitemap/xmlsitemap.xmlsitemap.inc
  71. 76 0
      sites/all/modules/xmlsitemap/xmlsitemap_custom/README.txt
  72. 27 5
      sites/all/modules/xmlsitemap/xmlsitemap_custom/xmlsitemap_custom.admin.inc
  73. 3 7
      sites/all/modules/xmlsitemap/xmlsitemap_custom/xmlsitemap_custom.info
  74. 6 1
      sites/all/modules/xmlsitemap/xmlsitemap_custom/xmlsitemap_custom.module
  75. 36 11
      sites/all/modules/xmlsitemap/xmlsitemap_custom/xmlsitemap_custom.test
  76. 79 0
      sites/all/modules/xmlsitemap/xmlsitemap_engines/README.txt
  77. 86 11
      sites/all/modules/xmlsitemap/xmlsitemap_engines/tests/xmlsitemap_engines.test
  78. 3 6
      sites/all/modules/xmlsitemap/xmlsitemap_engines/tests/xmlsitemap_engines_test.info
  79. 9 0
      sites/all/modules/xmlsitemap/xmlsitemap_engines/tests/xmlsitemap_engines_test.module
  80. 19 2
      sites/all/modules/xmlsitemap/xmlsitemap_engines/xmlsitemap_engines.admin.inc
  81. 1 1
      sites/all/modules/xmlsitemap/xmlsitemap_engines/xmlsitemap_engines.api.php
  82. 3 7
      sites/all/modules/xmlsitemap/xmlsitemap_engines/xmlsitemap_engines.info
  83. 36 24
      sites/all/modules/xmlsitemap/xmlsitemap_engines/xmlsitemap_engines.module
  84. 3 5
      sites/all/modules/xmlsitemap/xmlsitemap_i18n/xmlsitemap_i18n.info
  85. 11 1
      sites/all/modules/xmlsitemap/xmlsitemap_i18n/xmlsitemap_i18n.module
  86. 43 6
      sites/all/modules/xmlsitemap/xmlsitemap_i18n/xmlsitemap_i18n.test
  87. 79 0
      sites/all/modules/xmlsitemap/xmlsitemap_menu/README.txt
  88. 3 6
      sites/all/modules/xmlsitemap/xmlsitemap_menu/xmlsitemap_menu.info
  89. 44 18
      sites/all/modules/xmlsitemap/xmlsitemap_menu/xmlsitemap_menu.module
  90. 32 4
      sites/all/modules/xmlsitemap/xmlsitemap_menu/xmlsitemap_menu.test
  91. 3 5
      sites/all/modules/xmlsitemap/xmlsitemap_modal/xmlsitemap_modal.info
  92. 7 2
      sites/all/modules/xmlsitemap/xmlsitemap_modal/xmlsitemap_modal.module
  93. 81 0
      sites/all/modules/xmlsitemap/xmlsitemap_node/README.txt
  94. 3 6
      sites/all/modules/xmlsitemap/xmlsitemap_node/xmlsitemap_node.info
  95. 69 23
      sites/all/modules/xmlsitemap/xmlsitemap_node/xmlsitemap_node.module
  96. 97 17
      sites/all/modules/xmlsitemap/xmlsitemap_node/xmlsitemap_node.test
  97. 83 0
      sites/all/modules/xmlsitemap/xmlsitemap_taxonomy/README.txt
  98. 3 6
      sites/all/modules/xmlsitemap/xmlsitemap_taxonomy/xmlsitemap_taxonomy.info
  99. 1 1
      sites/all/modules/xmlsitemap/xmlsitemap_taxonomy/xmlsitemap_taxonomy.install
  100. 36 18
      sites/all/modules/xmlsitemap/xmlsitemap_taxonomy/xmlsitemap_taxonomy.module

+ 121 - 0
sites/all/modules/filefield_paths/.travis.yml

@@ -0,0 +1,121 @@
+# @file
+# .travis.yml - Drupal for Travis CI Integration
+#
+# Template provided by https://github.com/LionsAd/drupal_ti.
+#
+# Based for simpletest upon:
+#   https://github.com/sonnym/travis-ci-drupal-module-example
+
+language: php
+
+sudo: false
+
+php:
+  - 5.3
+  - 5.4
+  - 5.5
+  - 5.6
+  - 7
+
+matrix:
+  fast_finish: true
+  allow_failures:
+    - php: 7
+
+env:
+  global:
+    # add composer's global bin directory to the path
+    # see: https://github.com/drush-ops/drush#install---composer
+    - PATH="$PATH:$HOME/.composer/vendor/bin"
+
+    # Configuration variables.
+    - DRUPAL_TI_MODULE_NAME="filefield_paths"
+    - DRUPAL_TI_SIMPLETEST_GROUP="File (Field) Paths"
+
+    # Define runners and environment vars to include before and after the
+    # main runners / environment vars.
+    #- DRUPAL_TI_SCRIPT_DIR_BEFORE="./drupal_ti/before"
+    #- DRUPAL_TI_SCRIPT_DIR_AFTER="./drupal_ti/after"
+
+    # The environment to use, supported are: drupal-7, drupal-8
+    - DRUPAL_TI_ENVIRONMENT="drupal-7"
+
+    # Drupal specific variables.
+    - DRUPAL_TI_DB="drupal_travis_db"
+    - DRUPAL_TI_DB_URL="mysql://root:@127.0.0.1/drupal_travis_db"
+    # Note: Do not add a trailing slash here.
+    - DRUPAL_TI_WEBSERVER_URL="http://127.0.0.1"
+    - DRUPAL_TI_WEBSERVER_PORT="8080"
+
+    # Simpletest specific commandline arguments, the DRUPAL_TI_SIMPLETEST_GROUP is appended at the end.
+    - DRUPAL_TI_SIMPLETEST_ARGS="--verbose --color --concurrency 4 --url $DRUPAL_TI_WEBSERVER_URL:$DRUPAL_TI_WEBSERVER_PORT"
+
+    # === Behat specific variables.
+    # This is relative to $TRAVIS_BUILD_DIR
+    - DRUPAL_TI_BEHAT_DIR="./tests/behat"
+    # These arguments are passed to the bin/behat command.
+    - DRUPAL_TI_BEHAT_ARGS=""
+    # Specify the filename of the behat.yml with the $DRUPAL_TI_DRUPAL_DIR variables.
+    - DRUPAL_TI_BEHAT_YML="behat.yml.dist"
+    # This is used to setup Xvfb.
+    - DRUPAL_TI_BEHAT_SCREENSIZE_COLOR="1280x1024x16"
+    # The version of seleniumthat should be used.
+    - DRUPAL_TI_BEHAT_SELENIUM_VERSION="2.44"
+    # Set DRUPAL_TI_BEHAT_DRIVER to "selenium" to use "firefox" or "chrome" here.
+    - DRUPAL_TI_BEHAT_DRIVER="phantomjs"
+    - DRUPAL_TI_BEHAT_BROWSER="firefox"
+
+    # PHPUnit specific commandline arguments.
+    - DRUPAL_TI_PHPUNIT_ARGS=""
+    # Specifying the phpunit-core src/ directory is useful when e.g. a vendor/
+    # directory is present in the module directory, which phpunit would then
+    # try to find tests in. This option is relative to $TRAVIS_BUILD_DIR.
+    #- DRUPAL_TI_PHPUNIT_CORE_SRC_DIRECTORY="./tests/src"
+
+    # Code coverage via coveralls.io
+    - DRUPAL_TI_COVERAGE="satooshi/php-coveralls:0.6.*"
+    # This needs to match your .coveralls.yml file.
+    - DRUPAL_TI_COVERAGE_FILE="build/logs/clover.xml"
+
+    # Debug options
+    #- DRUPAL_TI_DEBUG="-x -v"
+    # Set to "all" to output all files, set to e.g. "xvfb selenium" or "selenium",
+    # etc. to only output those channels.
+    #- DRUPAL_TI_DEBUG_FILE_OUTPUT="selenium xvfb webserver"
+
+  matrix:
+    # [[[ SELECT ANY OR MORE OPTIONS ]]]
+    #- DRUPAL_TI_RUNNERS="phpunit"
+    #- DRUPAL_TI_RUNNERS="simpletest"
+    #- DRUPAL_TI_RUNNERS="behat"
+    #- DRUPAL_TI_RUNNERS="phpunit simpletest behat"
+    # Use phpunit-core to test modules with phpunit with Drupal 8 core.
+    #- DRUPAL_TI_RUNNERS="phpunit-core"
+    - DRUPAL_TI_RUNNERS="simpletest"
+
+mysql:
+  database: drupal_travis_db
+  username: root
+  encoding: utf8
+
+before_install:
+  - composer self-update
+  - cd ./tests
+  - composer global require "lionsad/drupal_ti:1.*"
+  - drupal-ti before_install
+
+install:
+  - drupal-ti install
+
+before_script:
+  - drupal-ti before_script
+  - drush dl pathauto-7.x redirect-7.x token-7.x transliteration-7.x --destination="$TRAVIS_BUILD_DIR/../drupal-7/drupal/sites/all/modules"
+
+script:
+  - drupal-ti script
+
+after_script:
+  - drupal-ti after_script
+
+notifications:
+  email: false

+ 100 - 1
sites/all/modules/filefield_paths/CHANGELOG.txt

@@ -1,4 +1,100 @@
-File (Field) Paths 7.x-1.x-dev, xxxx-xx-xx (development release)
+File (Field) Paths 7.x-1.1, 2018-08-14
+--------------------------------------------------------------------------------
+
+- Fixed security issue
+- #2643026: Fixed issue when anonymous function not created.
+
+
+
+File (Field) Paths 7.x-1.0, 2015-11-17
+--------------------------------------------------------------------------------
+
+- #2615704 by morenstrat: Fixed issue with temporary path and schemes.
+- Added variable module integration.
+
+
+
+File (Field) Paths 7.x-1.0-rc3, 2015-11-11
+--------------------------------------------------------------------------------
+
+- #2612396: Added watchdog message for unmoved files.
+- #2607302: Added configurable temporary file location.
+
+
+
+File (Field) Paths 7.x-1.0-rc2, 2015-10-28
+--------------------------------------------------------------------------------
+
+- #2592519: Fixed issue with temporary upload location and field collections.
+- #2576547: Fixed issue with Media Youtube files being processed.
+- #2570127: Added stricter checks for filefield_paths_form_alter().
+- #2569589: Fixed issue with unicode characters in pathauto processing.
+
+
+
+File (Field) Paths 7.x-1.0-rc1, 2015-09-15
+--------------------------------------------------------------------------------
+
+- #2551187: Changed token tree to dialog.
+- #2514874 by Deciphered, smithmilner: Fixed issue with Drush command and
+    permissions.
+- #2468547 by Deciphered, smithmilner: Added Redirect module integration.
+- #2398411: Added default value of file_directory to file path.
+- #2395903: Added truncating of long file paths.
+- #2383527: Changed unprocessed destination to temporary://.
+- #2276435 by Deciphered, david_garcia, rajmataj: Fixed issue with retroactive
+    updates and instance settings.
+- #2271595 by Deciphered, tstoeckler, Reg: Fixed issue with empty batch.
+- #2214409: Updated field form layout.
+- #2211665: Added File path validation to remove unnecessary slashes.
+- #2103151 by Deciphered, david_garcia, Sumeet.Pareek, kitikonti, kolier:
+    Fixed deprecated /e modifier in preg_replace().
+- #2185755 by treksler: Fixed issue with regex, backreferences and numbers.
+- #2119789: Fixed issue with complex characters in regex functionality.
+- #2068365 by Deciphered, vinmassaro: Fixed issue when no instance in update.
+- #2047835: Fixed issue with pathauto replacemenets and periods (.).
+- #2019723 by Deciphered, szantog, jcandan, justafish: Fixed issue with remote
+    file stream wrappers.
+- #1985650: Fixed issue with moved Drush file in .info.
+- #1985280 by Deciphered, drasgardian: Fixed issue with hook_entity_update()
+    foreach loop.
+- #1942720 by Deciphered, kaare, alex.designworks, pp, BWPanda: Added slash
+    cleanup functionality.
+- #1854450: Updated file processing logic.
+- #1495716/#1986472: Fixed issue with D6 -> D7 upgrade path.
+- #1292436 by maximpodorov, InternetDevels: Fixed issue pathinfo and UTF files.
+- Added tests.
+- Removed dependency on the Token module.
+
+
+
+File (Field) Paths 7.x-1.0-beta4, 2013-04-25
+--------------------------------------------------------------------------------
+
+- #1945148: Fixed issue with File path cleanup process.
+- #1942720 by pp: Fixed issue with cleanup wehn token contains a '/' character.
+- #1925298 by David_Rothstein: Fixed issue with Image derivatives.
+- #1866450: Fixed issue with foreign characters in Regex.
+- #1714596: Fixed issue with file_attach_update() introduced in Drupal 7.15.
+- #1705298: Fixed extra beggining slash.
+- #1601104 by tseven: Fixed notice when no extension present.
+- #1572206: Add ability to disable for certain fields.
+- #1549474: Fixed path replacement in summary text.
+- #1512466 by maximpodorov, perarnet: Fixed issue with multi-value updates.
+- #1499442 by hass: Improved translatable strings.
+- #1464404: Fixed issue with field_attach_update().
+- #1438290 by xtfer: Fixed D6 to D7 upgrade path.
+- #1432200: Fixed issue with missing langcode variable.
+- #1420700: Fixed issue with pass-by-reference issue.
+- #1364492 by j0rd, Deciphered: Improved require_once routine.
+- #1361884 by burningdog, dwkitchen, Deciphered: Fixed processing remote files.
+- #1262828 by Pablo Gosse: Fixed issue with regex.
+- #860848 by mostou: Fixed File name field length.
+- Fixed issue with malformed URIs.
+
+
+
+File (Field) Paths 7.x-1.0-beta3, 2012-02-08
 --------------------------------------------------------------------------------
 --------------------------------------------------------------------------------
 
 
 - #1429238 by ocanzillon: Fixed Drush command syntax error.
 - #1429238 by ocanzillon: Fixed Drush command syntax error.
@@ -6,6 +102,7 @@ File (Field) Paths 7.x-1.x-dev, xxxx-xx-xx (development release)
 - Changed a large chunk of core functionality to simplify.
 - Changed a large chunk of core functionality to simplify.
 
 
 
 
+
 File (Field) Paths 7.x-1.0-beta2, 2012-02-05
 File (Field) Paths 7.x-1.0-beta2, 2012-02-05
 --------------------------------------------------------------------------------
 --------------------------------------------------------------------------------
 
 
@@ -16,6 +113,7 @@ File (Field) Paths 7.x-1.0-beta2, 2012-02-05
 - Added support for Video module.
 - Added support for Video module.
 
 
 
 
+
 File (Field) Paths 7.x-1.0-beta1, 2011-11-08
 File (Field) Paths 7.x-1.0-beta1, 2011-11-08
 --------------------------------------------------------------------------------
 --------------------------------------------------------------------------------
 
 
@@ -36,5 +134,6 @@ File (Field) Paths 7.x-1.0-beta1, 2011-11-08
 - Added Entity support.
 - Added Entity support.
 
 
 
 
+
 File (Field) Paths 7.x-1.0-alpha1, 2011-06-12
 File (Field) Paths 7.x-1.0-alpha1, 2011-06-12
 --------------------------------------------------------------------------------
 --------------------------------------------------------------------------------

+ 47 - 34
sites/all/modules/filefield_paths/README.txt → sites/all/modules/filefield_paths/README.md

@@ -1,63 +1,66 @@
-The File (Field) Paths module extends the default functionality of Drupals core
+File (Field) Paths
+==================
+
+[![Build Status](https://travis-ci.org/Decipher/filefield_paths.svg)](https://travis-ci.org/Decipher/filefield_paths)
+
+The File (Field) Paths module extends the default functionality of Drupal's core
 File module, Image module and many other File upload modules, by adding the
 File module, Image module and many other File upload modules, by adding the
-ability to use entity based tokens in destination paths and filenames.
+ability to use entity based tokens in destination paths and file names.
 
 
 In simple terms, File (Field) Paths allows you to automatically sort and rename
 In simple terms, File (Field) Paths allows you to automatically sort and rename
 your uploaded files using token based replacement patterns to maintain a nice
 your uploaded files using token based replacement patterns to maintain a nice
 clean filesystem.
 clean filesystem.
 
 
-File (Field) Paths was written and is maintained by Stuart Clark (deciphered).
-- http://stuar.tc/lark
-- http://twitter.com/Decipher
 
 
 
 
 Features
 Features
---------------------------------------------------------------------------------
+--------
 
 
 * Configurable file paths now use entity tokens in addition to user tokens.
 * Configurable file paths now use entity tokens in addition to user tokens.
-* Configurable filenames.
-* Support for:
-  * Drupal core File module.
-  * Drupal core Image module.
-  * Video module.
+* Configurable file names.
+* Support for file based fields, including but not limited to:
+    * Drupal core File module.
+    * Drupal core Image module.
+    * Video module.
 * File path and filename cleanup options:
 * File path and filename cleanup options:
-  * Filter out words and punctuation by taking advantage of the Pathauto module.
-  * Convert unicode characters into US-ASCII with the Transliteration module.
+    * Remove slashes from tokens.
+    * Filter out words and punctuation by taking advantage of the Pathauto
+      module.
+    * Convert unicode characters into US-ASCII with the Transliteration module.
 * Automatically updates unprocessed file paths in any Text fields on the entity.
 * Automatically updates unprocessed file paths in any Text fields on the entity.
-* Retroactive updates - rename and/or move previously uploaded files (Use with
-  caution)
-
+* Retroactive updates - rename and/or move previously uploaded files.
+* Active updating - actively rename and/or move previously uploaded files.
+* Create redirect - automatically create a redirect when moving uploaded files,
+  using the Redirect module.
 
 
-Required Modules
---------------------------------------------------------------------------------
-
-* Token           - http://drupal.org/project/token
 
 
 
 
 Recommended Modules
 Recommended Modules
---------------------------------------------------------------------------------
+-------------------
+
+* [Pathauto](https://www.drupal.org/project/pathauto)
+* [Redirect](https://www.drupal.org/project/redirect)
+* [Token](https://www.drupal.org/project/token)
+* [Transliteration](https://www.drupal.org/project/transliteration)
 
 
-* Pathauto        - http://drupal.org/project/pathauto
-* Transliteration - http://drupal.org/project/transliteration
 
 
 
 
 Usage/Configuration
 Usage/Configuration
---------------------------------------------------------------------------------
+-------------------
 
 
 Once installed, File (Field) Paths needs to be configured for each file field
 Once installed, File (Field) Paths needs to be configured for each file field
-you wish to use.
-
-* Drupal core File/Image and other Field based supported modules
-  Settings an be found on the fields configuration page.
+you wish to use. Settings can be found on the settings form of any supported
+file based field.
 
 
-  Example:
+  *Example:*
+  
     Administration > Structure > Content types > Article > Manage fields > Image
     Administration > Structure > Content types > Article > Manage fields > Image
-    http://[www.yoursite.com/path/to/drupal]/admin/structure/types/manage/article/fields/field_image
+    http://example.com/admin/structure/types/manage/article/fields/field_image
 
 
 
 
 
 
 Frequently Asked Questions
 Frequently Asked Questions
---------------------------------------------------------------------------------
+--------------------------
 
 
 Q. Aren't tokens already supported in the File module?
 Q. Aren't tokens already supported in the File module?
 
 
@@ -71,9 +74,9 @@ Q. Why aren't my files in the correct folder?
 
 
 A. When you are creating or updating an entity the full values for the tokens
 A. When you are creating or updating an entity the full values for the tokens
    may not yet be known by Drupal, so the File (Field) Paths module will upload
    may not yet be known by Drupal, so the File (Field) Paths module will upload
-   your files to the Fields old file path temporarily and then once you save the
-   entity and Drupal is provided with the tokens values the file will be moved
-   to the appropriate location.
+   your files to a temporary location and then once you save the entity and
+   Drupal is provided with the tokens values the file will be moved to the
+   appropriate location.
 
 
 
 
 Q. Why is there a warning on the 'Retroactive updates' feature?
 Q. Why is there a warning on the 'Retroactive updates' feature?
@@ -85,3 +88,13 @@ A. Retroactive updates will go through every single entity of the particular
    possible that the moving/renaming of these files could break links. It is
    possible that the moving/renaming of these files could break links. It is
    strongly advised that you only use this functionality on your developmental
    strongly advised that you only use this functionality on your developmental
    servers so that you can make sure not to introduce any linking issues.
    servers so that you can make sure not to introduce any linking issues.
+
+
+
+History and Maintainers
+-----------------------
+
+File (Field) Paths was written and is maintained by Stuart Clark (deciphered).
+
+* http://stuar.tc/lark
+* http://twitter.com/Decipher

+ 49 - 0
sites/all/modules/filefield_paths/filefield_paths.admin.inc

@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * @file
+ *
+ * Administration functions for the File (Field) Paths module.
+ */
+
+/**
+ * @param $form
+ * @param $form_state
+ * @return mixed
+ */
+function filefield_paths_settings_form($form, $form_state) {
+  $form['filefield_paths_temp_location'] = array(
+    '#title'            => t('Temporary file location'),
+    '#type'             => 'textfield',
+    '#default_value'    => variable_get('filefield_paths_temp_location', 'public://filefield_paths'),
+    '#description'      => t('The location that unprocessed files will be uploaded priot to being processed by File (Field) Paths.<br />It is recommended that you use the temporary file system (temporary://) if your server configuration allows for that.'),
+    '#element_validate' => array('filefield_paths_settings_form_temp_location_validate'),
+  );
+
+  return system_settings_form($form);
+}
+
+/**
+ * Validation callback for 'Temporary file location' setting.
+ *
+ * @param $element
+ * @param $form_state
+ * @return bool
+ */
+function filefield_paths_settings_form_temp_location_validate($element, $form_state) {
+  $scheme = file_uri_scheme($element['#value']);
+  if (!$scheme) {
+    form_error($element, t('Invalid file location. You must include a file stream wrapper (e.g., public://).'));
+    return FALSE;
+  }
+
+  if (!file_stream_wrapper_valid_scheme($scheme)) {
+    form_error($element, t('Invalid file stream wrapper.'));
+    return FALSE;
+  }
+
+  if ((!is_dir($element['#value']) || !is_writable($element['#value'])) && !file_prepare_directory($element['#value'], FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
+    form_error($element, t('File location can not be created or is not writable.'));
+    return FALSE;
+  }
+}

+ 71 - 0
sites/all/modules/filefield_paths/filefield_paths.api.php

@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * @file
+ * Hooks provided by the File (Field) Paths module.
+ */
+
+/**
+ * Define field(s) to be displayed on the File (Field) Paths settings form and
+ * used during the processing of uploaded files.
+ *
+ * @param $field
+ *   The field definition this File (Field) Paths settings field applies to.
+ * @param $instance
+ *   The field instance this File (Field) Paths settings field applies to.
+ *
+ * @return array
+ *   An array whose keys are field names and whose values are arrays defining
+ *   the field, with the following key/value pairs:
+ *   - title: The title fo the field.
+ *   - form: A keyed array of Form API elements.
+ *
+ * @see hook_filefield_paths_process_file().
+ */
+function hook_filefield_paths_field_settings($field, $instance) {
+  return array(
+    'file_path' => array(
+      'title' => 'File path',
+      'form'  => array(
+        'value' => array(
+          '#type'             => 'textfield',
+          '#title'            => t('File path'),
+          '#maxlength'        => 512,
+          '#size'             => 128,
+          '#element_validate' => array('_file_generic_settings_file_directory_validate'),
+          '#default_value'    => $instance['settings']['file_directory'],
+        ),
+      ),
+    ),
+  );
+}
+
+/**
+ * Declare a compatible field type for use with File (Field) Paths.
+ *
+ * @return array
+ */
+function hook_filefield_paths_field_type_info() {
+  return array('file');
+}
+
+/**
+ * Process the uploaded files.
+ *
+ * @param $type
+ *   The entity type containing the files for processing.
+ * @param $entity
+ *   The entity containing the files for processing.
+ * @param $field
+ *   The definition of the field containing the files for processing.
+ * @param $instance
+ *   The instance of the field containing the files for processing.
+ * @param $langcode
+ *   The language code of the field containing the files for processing.
+ * @param $items
+ *   A pass-by-reference array of all the files for processing.
+ *
+ * @see filefield_paths_filefield_paths_process_file().
+ */
+function hook_filefield_paths_process_file($type, $entity, $field, $instance, $langcode, &$items) {
+}

+ 29 - 14
sites/all/modules/filefield_paths/modules/filefield_paths.drush.inc → sites/all/modules/filefield_paths/filefield_paths.drush.inc

@@ -1,4 +1,5 @@
 <?php
 <?php
+
 /**
 /**
  * @file
  * @file
  * Drush integration.
  * Drush integration.
@@ -12,20 +13,20 @@ function filefield_paths_drush_command() {
 
 
   $items['ffp-update'] = array(
   $items['ffp-update'] = array(
     'description' => 'Retroactively updates all File (Field) Paths of a chosen field instance.',
     'description' => 'Retroactively updates all File (Field) Paths of a chosen field instance.',
-    'arguments' => array(
+    'arguments'   => array(
       'entity_type' => 'Entity type.',
       'entity_type' => 'Entity type.',
       'bundle_name' => 'Bundle name.',
       'bundle_name' => 'Bundle name.',
-      'field_name' => 'Field name.'
+      'field_name'  => 'Field name.'
     ),
     ),
-    'options' => array(
+    'options'     => array(
       'all' => 'Retroactively update all File (Field) Paths.',
       'all' => 'Retroactively update all File (Field) Paths.',
     ),
     ),
-    'examples' => array(
-      'drush ffp-update' => 'Retroactively updates the File (Field) Paths of the instances choosen via an interactive menu.',
+    'examples'    => array(
+      'drush ffp-update'                          => 'Retroactively updates the File (Field) Paths of the instances choosen via an interactive menu.',
       'drush ffp-update node article field_image' => 'Retroactively updates the File (Field) Paths of all instances of the Article content types Image field.',
       'drush ffp-update node article field_image' => 'Retroactively updates the File (Field) Paths of all instances of the Article content types Image field.',
-      'drush ffp-update --all' => 'Retroactively update all File (Field) Paths.',
+      'drush ffp-update --all'                    => 'Retroactively update all File (Field) Paths.',
     ),
     ),
-    'aliases' => array('ffpu'),
+    'aliases'     => array('ffpu'),
   );
   );
 
 
   return $items;
   return $items;
@@ -33,17 +34,23 @@ function filefield_paths_drush_command() {
 
 
 /**
 /**
  * Retroactively updates all File (Field) Paths of a chosen field instance.
  * Retroactively updates all File (Field) Paths of a chosen field instance.
+ *
+ * @param null $entity_type
+ * @param null $bundle_name
+ * @param null $field_name
+ *
+ * @return string
  */
  */
 function drush_filefield_paths_ffp_update($entity_type = NULL, $bundle_name = NULL, $field_name = NULL) {
 function drush_filefield_paths_ffp_update($entity_type = NULL, $bundle_name = NULL, $field_name = NULL) {
   // Build array of information of all entity types, bundle names and field
   // Build array of information of all entity types, bundle names and field
   // names.
   // names.
   $field_types = array_keys(_filefield_paths_get_field_types());
   $field_types = array_keys(_filefield_paths_get_field_types());
-  $info = array();
+  $info        = array();
   foreach (field_info_fields() as $field) {
   foreach (field_info_fields() as $field) {
     if (in_array($field['type'], $field_types)) {
     if (in_array($field['type'], $field_types)) {
       foreach ($field['bundles'] as $entity_type_name => $bundles) {
       foreach ($field['bundles'] as $entity_type_name => $bundles) {
         if (!isset($info[$entity_type_name])) {
         if (!isset($info[$entity_type_name])) {
-          $entity_type_info = entity_get_info($entity_type_name);
+          $entity_type_info        = entity_get_info($entity_type_name);
           $info[$entity_type_name] = array(
           $info[$entity_type_name] = array(
             '#label' => "{$entity_type_info['label']} ({$entity_type_name})",
             '#label' => "{$entity_type_info['label']} ({$entity_type_name})",
           );
           );
@@ -56,6 +63,7 @@ function drush_filefield_paths_ffp_update($entity_type = NULL, $bundle_name = NU
             );
             );
           }
           }
           $field = field_info_instance($entity_type_name, $field['field_name'], $bundle);
           $field = field_info_instance($entity_type_name, $field['field_name'], $bundle);
+
           $info[$entity_type_name][$bundle][$field['field_name']] = "{$field['label']} ({$field['field_name']})";
           $info[$entity_type_name][$bundle][$field['field_name']] = "{$field['label']} ({$field['field_name']})";
         }
         }
       }
       }
@@ -72,6 +80,7 @@ function drush_filefield_paths_ffp_update($entity_type = NULL, $bundle_name = NU
       }
       }
     }
     }
     _filefield_paths_drush_ffp_update($instances);
     _filefield_paths_drush_ffp_update($instances);
+
     return '';
     return '';
   }
   }
 
 
@@ -96,6 +105,7 @@ function drush_filefield_paths_ffp_update($entity_type = NULL, $bundle_name = NU
       }
       }
     }
     }
     _filefield_paths_drush_ffp_update($instances);
     _filefield_paths_drush_ffp_update($instances);
+
     return '';
     return '';
   }
   }
 
 
@@ -118,6 +128,7 @@ function drush_filefield_paths_ffp_update($entity_type = NULL, $bundle_name = NU
       }
       }
     }
     }
     _filefield_paths_drush_ffp_update($instances);
     _filefield_paths_drush_ffp_update($instances);
+
     return '';
     return '';
   }
   }
 
 
@@ -138,6 +149,7 @@ function drush_filefield_paths_ffp_update($entity_type = NULL, $bundle_name = NU
       $instances[] = field_info_instance($entity_type, $field_name, $bundle_name);
       $instances[] = field_info_instance($entity_type, $field_name, $bundle_name);
     }
     }
     _filefield_paths_drush_ffp_update($instances);
     _filefield_paths_drush_ffp_update($instances);
+
     return '';
     return '';
   }
   }
 
 
@@ -148,13 +160,16 @@ function drush_filefield_paths_ffp_update($entity_type = NULL, $bundle_name = NU
 
 
 /**
 /**
  * Helper function; Invokes File (Field) Paths Retroactive updates.
  * Helper function; Invokes File (Field) Paths Retroactive updates.
+ *
+ * @param $instances
  */
  */
 function _filefield_paths_drush_ffp_update($instances) {
 function _filefield_paths_drush_ffp_update($instances) {
   foreach ($instances as $instance) {
   foreach ($instances as $instance) {
-    filefield_paths_batch_update($instance);
-    $batch =& batch_get();
-    $batch['progressive'] = FALSE;
-    drush_backend_batch_process();
-    drush_log(dt('!field_name File (Field) Paths updated.', array('!field_name' => "{$instance['label']} ({$instance['entity_type']}-{$instance['bundle']}-{$instance['field_name']})")), 'success');
+    if (filefield_paths_batch_update($instance)) {
+      $batch                =& batch_get();
+      $batch['progressive'] = FALSE;
+      drush_backend_batch_process();
+      drush_log(dt('!field_name File (Field) Paths updated.', array('!field_name' => "{$instance['label']} ({$instance['entity_type']}-{$instance['bundle']}-{$instance['field_name']})")), 'success');
+    }
   }
   }
 }
 }

+ 18 - 15
sites/all/modules/filefield_paths/filefield_paths.info

@@ -1,25 +1,28 @@
 name = File (Field) Paths
 name = File (Field) Paths
 description = Adds improved Token based file sorting and renaming functionalities.
 description = Adds improved Token based file sorting and renaming functionalities.
-dependencies[] = token
 package = Fields
 package = Fields
+test_dependencies[] = pathauto
+test_dependencies[] = redirect
+test_dependencies[] = token
+test_dependencies[] = transliteration
+configure = admin/config/media/file-system/filefield-paths
 core = 7.x
 core = 7.x
 
 
-files[] = filefield_paths.install
-files[] = filefield_paths.module
 
 
-files[] = modules/features.inc
-files[] = modules/file.inc
-files[] = modules/filefield_paths.drush.inc
-files[] = modules/filefield_paths.inc
-files[] = modules/image.inc
-files[] = modules/token.inc
-files[] = modules/video.inc
 
 
-;files[] = tests/filefield_paths.test
+; Simpletest files.
 
 
-; Information added by drupal.org packaging script on 2012-02-07
-version = "7.x-1.0-beta3"
+files[] = tests/filefield_paths.test
+files[] = tests/filefield_paths.general.test
+files[] = tests/filefield_paths.text_replace.test
+files[] = tests/filefield_paths.tokens.test
+files[] = tests/filefield_paths.update.test
+files[] = tests/pathauto.test
+files[] = tests/redirect.test
+files[] = tests/transliteration.test
+
+; Information added by Drupal.org packaging script on 2018-08-14
+version = "7.x-1.1"
 core = "7.x"
 core = "7.x"
 project = "filefield_paths"
 project = "filefield_paths"
-datestamp = "1328655041"
-
+datestamp = "1534256584"

+ 58 - 35
sites/all/modules/filefield_paths/filefield_paths.install

@@ -1,4 +1,5 @@
 <?php
 <?php
+
 /**
 /**
  * @file
  * @file
  * Install, update and uninstall functions for the File (Field) Paths module.
  * Install, update and uninstall functions for the File (Field) Paths module.
@@ -13,10 +14,10 @@
 function filefield_paths_schema_alter(&$schema) {
 function filefield_paths_schema_alter(&$schema) {
   $schema['file_managed']['fields']['origname'] = array(
   $schema['file_managed']['fields']['origname'] = array(
     'description' => 'Original name of the file.',
     'description' => 'Original name of the file.',
-    'type' => 'varchar',
-    'length' => 255,
-    'not null' => TRUE,
-    'default' => '',
+    'type'        => 'varchar',
+    'length'      => 255,
+    'not null'    => TRUE,
+    'default'     => '',
   );
   );
 }
 }
 
 
@@ -28,14 +29,12 @@ function filefield_paths_install() {
   // filenames.
   // filenames.
   db_add_field('file_managed', 'origname', array(
   db_add_field('file_managed', 'origname', array(
     'description' => 'Original name of the file with no path components. Used by the filefield_paths module.',
     'description' => 'Original name of the file with no path components. Used by the filefield_paths module.',
-    'type' => 'varchar',
-    'length' => 255,
-    'not null' => TRUE,
-    'default' => '',
+    'type'        => 'varchar',
+    'length'      => 255,
+    'not null'    => TRUE,
+    'default'     => '',
   ));
   ));
-  db_update('file_managed')
-    ->expression('origname', 'filename')
-    ->execute();
+  db_update('file_managed')->expression('origname', 'filename')->execute();
 }
 }
 
 
 /**
 /**
@@ -76,10 +75,10 @@ function filefield_paths_update_7103() {
   if (!db_field_exists('file_managed', 'origname')) {
   if (!db_field_exists('file_managed', 'origname')) {
     db_add_field('file_managed', 'origname', array(
     db_add_field('file_managed', 'origname', array(
       'description' => 'Original name of the file with no path components. Used by the filefield_paths module.',
       'description' => 'Original name of the file with no path components. Used by the filefield_paths module.',
-      'type' => 'varchar',
-      'length' => 255,
-      'not null' => TRUE,
-      'default' => '',
+      'type'        => 'varchar',
+      'length'      => 255,
+      'not null'    => TRUE,
+      'default'     => '',
     ));
     ));
   }
   }
   db_update('file_managed')
   db_update('file_managed')
@@ -93,10 +92,10 @@ function filefield_paths_update_7103() {
  */
  */
 function filefield_paths_update_7104() {
 function filefield_paths_update_7104() {
   db_add_field('filefield_paths', 'active_updating', array(
   db_add_field('filefield_paths', 'active_updating', array(
-    'type' => 'int',
-    'size' => 'tiny',
+    'type'     => 'int',
+    'size'     => 'tiny',
     'not null' => TRUE,
     'not null' => TRUE,
-    'default' => '0'
+    'default'  => '0'
   ));
   ));
 
 
   // migrate variable to filefield_paths table
   // migrate variable to filefield_paths table
@@ -123,10 +122,10 @@ function filefield_paths_update_7104() {
  */
  */
 function filefield_paths_update_7105() {
 function filefield_paths_update_7105() {
   db_change_field('filefield_paths', 'active_updating', 'active_updating', array(
   db_change_field('filefield_paths', 'active_updating', 'active_updating', array(
-    'type' => 'int',
-    'size' => 'tiny',
+    'type'     => 'int',
+    'size'     => 'tiny',
     'not null' => TRUE,
     'not null' => TRUE,
-    'default' => 0
+    'default'  => 0
   ));
   ));
 }
 }
 
 
@@ -135,16 +134,16 @@ function filefield_paths_update_7105() {
  */
  */
 function filefield_paths_update_7106() {
 function filefield_paths_update_7106() {
   db_change_field('filefield_paths', 'type', 'type', array(
   db_change_field('filefield_paths', 'type', 'type', array(
-    'type' => 'varchar',
-    'length' => 128,
+    'type'     => 'varchar',
+    'length'   => 128,
     'not null' => TRUE,
     'not null' => TRUE,
-    'default' => ''
+    'default'  => ''
   ));
   ));
   db_change_field('filefield_paths', 'field', 'field', array(
   db_change_field('filefield_paths', 'field', 'field', array(
-    'type' => 'varchar',
-    'length' => 128,
+    'type'     => 'varchar',
+    'length'   => 128,
     'not null' => TRUE,
     'not null' => TRUE,
-    'default' => ''
+    'default'  => ''
   ));
   ));
 }
 }
 
 
@@ -152,33 +151,57 @@ function filefield_paths_update_7106() {
  * Removed filefield_paths table/schema.
  * Removed filefield_paths table/schema.
  */
  */
 function filefield_paths_update_7107() {
 function filefield_paths_update_7107() {
+  $results = db_select('filefield_paths', 'ffp')->fields('ffp')->execute();
+  foreach ($results as $result) {
+    $instance = field_info_instance('node', $result->field, $result->type);
+    if (!is_null($instance) && isset($instance["ffp_{$result->field}}"])) {
+      $filepath = unserialize($result->filepath);
+      $filename = unserialize($result->filename);
+
+      $instance["ffp_{$result->field}"] = array(
+        'file_path'         => $filepath['value'],
+        'file_path_cleanup' => array(
+          'file_path_pathauto'      => $filepath['pathauto'],
+          'file_path_transliterate' => $filepath['transliterate'],
+        ),
+        'file_name'         => $filename['value'],
+        'file_name_cleanup' => array(
+          'file_name_pathauto'      => $filename['pathauto'],
+          'file_name_transliterate' => $filename['transliterate'],
+        ),
+        'active_updating'   => $result->active_updating,
+      );
+      field_update_instance($instance);
+    }
+  }
+
   // Remove filefield_paths table/schema.
   // Remove filefield_paths table/schema.
   db_drop_table('filefield_paths');
   db_drop_table('filefield_paths');
 
 
   // Update field instance settings.
   // Update field instance settings.
+  drupal_load('module', 'filefield_paths');
   $field_types = array_keys(_filefield_paths_get_field_types());
   $field_types = array_keys(_filefield_paths_get_field_types());
   foreach (field_info_fields() as $field) {
   foreach (field_info_fields() as $field) {
     if (in_array($field['type'], $field_types)) {
     if (in_array($field['type'], $field_types)) {
       foreach ($field['bundles'] as $entity_type => $bundles) {
       foreach ($field['bundles'] as $entity_type => $bundles) {
         foreach ($bundles as $bundle_name) {
         foreach ($bundles as $bundle_name) {
           $instance = field_info_instance($entity_type, $field['field_name'], $bundle_name);
           $instance = field_info_instance($entity_type, $field['field_name'], $bundle_name);
-          if ($instance["ffp_{$field['field_name']}"] && !isset($instance['settings']['filefield_paths'])) {
+          if (isset($instance["ffp_{$field['field_name']}"]) && !isset($instance['settings']['filefield_paths'])) {
             $instance['settings']['filefield_paths'] = array(
             $instance['settings']['filefield_paths'] = array(
-              'file_path' => array(
-                'value' => $instance["ffp_{$field['field_name']}"]['file_path'],
+              'file_path'       => array(
+                'value'   => $instance["ffp_{$field['field_name']}"]['file_path'],
                 'options' => array(
                 'options' => array(
-                  'pathauto' => $instance["ffp_{$field['field_name']}"]['file_path_cleanup']['file_path_pathauto'],
+                  'pathauto'      => $instance["ffp_{$field['field_name']}"]['file_path_cleanup']['file_path_pathauto'],
                   'transliterate' => $instance["ffp_{$field['field_name']}"]['file_path_cleanup']['file_path_transliterate'],
                   'transliterate' => $instance["ffp_{$field['field_name']}"]['file_path_cleanup']['file_path_transliterate'],
                 ),
                 ),
               ),
               ),
-              'file_name' => array(
-                'value' => $instance["ffp_{$field['field_name']}"]['file_name'],
+              'file_name'       => array(
+                'value'   => $instance["ffp_{$field['field_name']}"]['file_name'],
                 'options' => array(
                 'options' => array(
-                  'pathauto' => $instance["ffp_{$field['field_name']}"]['file_name_cleanup']['file_name_pathauto'],
+                  'pathauto'      => $instance["ffp_{$field['field_name']}"]['file_name_cleanup']['file_name_pathauto'],
                   'transliterate' => $instance["ffp_{$field['field_name']}"]['file_name_cleanup']['file_name_transliterate'],
                   'transliterate' => $instance["ffp_{$field['field_name']}"]['file_name_cleanup']['file_name_transliterate'],
                 ),
                 ),
               ),
               ),
-              'retroactive_update' => $instance["ffp_{$field['field_name']}"]['retroactive_update'],
               'active_updating' => $instance["ffp_{$field['field_name']}"]['active_updating'],
               'active_updating' => $instance["ffp_{$field['field_name']}"]['active_updating'],
             );
             );
             unset($instance["ffp_{$field['field_name']}"]);
             unset($instance["ffp_{$field['field_name']}"]);

+ 430 - 133
sites/all/modules/filefield_paths/filefield_paths.module

@@ -1,4 +1,5 @@
 <?php
 <?php
+
 /**
 /**
  * @file
  * @file
  * Contains core functions for the File (Field) Paths module.
  * Contains core functions for the File (Field) Paths module.
@@ -7,36 +8,78 @@
 /**
 /**
  * Include additional files.
  * Include additional files.
  */
  */
+$dirname  = dirname(__FILE__) . "/modules";
+$includes = file_scan_directory($dirname, '/.inc$/');
 foreach (module_list() as $module) {
 foreach (module_list() as $module) {
-  if (file_exists($file = dirname(__FILE__) . "/modules/{$module}.inc")) {
+  if (isset($includes[$file = "{$dirname}/{$module}.inc"])) {
     require_once $file;
     require_once $file;
   }
   }
 }
 }
 
 
+/**
+ * Implements hook_menu().
+ */
+function filefield_paths_menu() {
+  $items['admin/config/media/file-system/filefield-paths'] = array(
+    'title'            => t('File (Field) Paths settings'),
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('filefield_paths_settings_form'),
+    'access arguments' => array('administer site configuration'),
+    'type'             => MENU_NORMAL_ITEM,
+    'file'             => 'filefield_paths.admin.inc',
+  );
+
+  return $items;
+}
+
 /**
 /**
  * Implements hook_form_alter().
  * Implements hook_form_alter().
+ *
+ * @param $form
  */
  */
-function filefield_paths_form_alter(&$form, $form_state, $form_id) {
+function filefield_paths_form_alter(&$form) {
+  // Force all File (Field) Paths uploads to go to the temporary file system
+  // prior to being processed.
+  if (isset($form['#entity']) && isset($form['#entity_type']) && isset($form['#bundle']) && $form['#type'] == 'form') {
+    filefield_paths_temporary_upload_location($form);
+  }
+
   $field_types = _filefield_paths_get_field_types();
   $field_types = _filefield_paths_get_field_types();
   if (isset($form['#field']) && in_array($form['#field']['type'], array_keys($field_types))) {
   if (isset($form['#field']) && in_array($form['#field']['type'], array_keys($field_types))) {
     $entity_info = entity_get_info($form['#instance']['entity_type']);
     $entity_info = entity_get_info($form['#instance']['entity_type']);
-    $settings = isset($form['#instance']['settings']['filefield_paths']) ? $form['#instance']['settings']['filefield_paths'] : array();
+    $settings    = isset($form['#instance']['settings']['filefield_paths']) ? $form['#instance']['settings']['filefield_paths'] : array();
+
+    $form['instance']['settings']['filefield_paths_enabled'] = array(
+      '#type'          => 'checkbox',
+      '#title'         => t('Enable File (Field) Paths?'),
+      '#default_value' => isset($form['#instance']['settings']['filefield_paths_enabled']) ? $form['#instance']['settings']['filefield_paths_enabled'] : TRUE,
+      '#weight'        => 2,
+    );
 
 
     // Hide standard File directory field.
     // Hide standard File directory field.
-    $form['instance']['settings']['file_directory']['#access'] = FALSE;
+    $form['instance']['settings']['file_directory']['#states'] = array(
+      'visible' => array(
+        ':input[name="instance[settings][filefield_paths_enabled]"]' => array('checked' => FALSE),
+      ),
+    );
 
 
     // File (Field) Paths fieldset element.
     // File (Field) Paths fieldset element.
     $form['instance']['settings']['filefield_paths'] = array(
     $form['instance']['settings']['filefield_paths'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('File (Field) Path settings'),
+      '#type'        => 'fieldset',
+      '#title'       => t('File (Field) Path settings'),
       '#collapsible' => TRUE,
       '#collapsible' => TRUE,
-      '#collapsed' => TRUE,
-      '#weight' => 1,
-      '#tree' => TRUE,
+      '#collapsed'   => TRUE,
+      '#weight'      => 3,
+      '#tree'        => TRUE,
+      '#states'      => array(
+        'visible' => array(
+          ':input[name="instance[settings][filefield_paths_enabled]"]' => array('checked' => TRUE),
+        ),
+      ),
     );
     );
 
 
     // Additional File (Field) Paths widget fields.
     // Additional File (Field) Paths widget fields.
-    $fields = module_invoke_all('filefield_paths_field_settings');
+    $fields = module_invoke_all('filefield_paths_field_settings', $form['#field'], $form['#instance']);
     foreach ($fields as $name => $field) {
     foreach ($fields as $name => $field) {
       // Attach widget fields.
       // Attach widget fields.
       $form['instance']['settings']['filefield_paths'][$name] = array(
       $form['instance']['settings']['filefield_paths'][$name] = array(
@@ -46,13 +89,14 @@ function filefield_paths_form_alter(&$form, $form_state, $form_id) {
       // Attach widget field form elements.
       // Attach widget field form elements.
       if (isset($field['form']) && is_array($field['form'])) {
       if (isset($field['form']) && is_array($field['form'])) {
         foreach (array_keys($field['form']) as $delta => $key) {
         foreach (array_keys($field['form']) as $delta => $key) {
-          $form['instance']['settings']['filefield_paths'][$name][$key] = array_merge(
-            $field['form'][$key],
-            array(
-              '#element_validate' => array('token_element_validate'),
-              '#token_types' => array('file', $entity_info['token type']),
-            )
-          );
+          $form['instance']['settings']['filefield_paths'][$name][$key] = $field['form'][$key];
+          if (module_exists('token')) {
+            $form['instance']['settings']['filefield_paths'][$name][$key]['#element_validate'][] = 'token_element_validate';
+            $form['instance']['settings']['filefield_paths'][$name][$key]['#token_types']        = array(
+              'file',
+              $entity_info['token type']
+            );
+          }
 
 
           // Fetch stored value from instance.
           // Fetch stored value from instance.
           if (isset($settings[$name][$key])) {
           if (isset($settings[$name][$key])) {
@@ -62,67 +106,82 @@ function filefield_paths_form_alter(&$form, $form_state, $form_id) {
 
 
         // Field options.
         // Field options.
         $form['instance']['settings']['filefield_paths'][$name]['options'] = array(
         $form['instance']['settings']['filefield_paths'][$name]['options'] = array(
-          '#type' => 'fieldset',
-          '#title' => t('@title options', array('@title' => $field['title'])),
+          '#type'        => 'fieldset',
+          '#title'       => t('@title options', array('@title' => t($field['title']))),
           '#collapsible' => TRUE,
           '#collapsible' => TRUE,
-          '#collapsed' => TRUE,
-          '#weight' => 1,
-          '#attributes' => array(
+          '#collapsed'   => TRUE,
+          '#weight'      => 1,
+          '#attributes'  => array(
             'class' => array("{$name} cleanup")
             'class' => array("{$name} cleanup")
           ),
           ),
         );
         );
-        // @TODO - Make this more modular.
+        // Cleanup slashes (/).
+        $form['instance']['settings']['filefield_paths'][$name]['options']['slashes'] = array(
+          '#type'          => 'checkbox',
+          '#title'         => t('Remove slashes (/) from tokens'),
+          '#default_value' => isset($settings[$name]['options']['slashes']) ? $settings[$name]['options']['slashes'] : FALSE,
+          '#description'   => t('If checked, any slashes (/) in tokens will be removed from %title.', array('%title' => t($field['title']))),
+        );
+
         // Cleanup field with Pathauto module.
         // Cleanup field with Pathauto module.
         $form['instance']['settings']['filefield_paths'][$name]['options']['pathauto'] = array(
         $form['instance']['settings']['filefield_paths'][$name]['options']['pathauto'] = array(
-          '#type' => 'checkbox',
-          '#title' => t('Cleanup using Pathauto') . '.',
-          '#default_value' => isset($settings[$name]['options']['pathauto']) && module_exists('pathauto')
-            ? $settings[$name]['options']['pathauto']
-            : FALSE,
-          '#description' => t('Cleanup @title using', array('@title' => $field['title'])) . ' ' . l(t('Pathauto settings'), 'admin/config/search/path/settings'),
-          '#disabled' => !module_exists('pathauto'),
+          '#type'          => 'checkbox',
+          '#title'         => t('Cleanup using Pathauto'),
+          '#default_value' => isset($settings[$name]['options']['pathauto']) && module_exists('pathauto') ? $settings[$name]['options']['pathauto'] : FALSE,
+          '#description'   => t('Cleanup %title using <a href="@pathauto">Pathauto settings</a>.', array(
+            '%title'    => t($field['title']),
+            '@pathauto' => url('admin/config/search/path/settings')
+          )),
+          '#disabled'      => !module_exists('pathauto'),
         );
         );
 
 
         // Transliterate field with Transliteration module.
         // Transliterate field with Transliteration module.
         $form['instance']['settings']['filefield_paths'][$name]['options']['transliterate'] = array(
         $form['instance']['settings']['filefield_paths'][$name]['options']['transliterate'] = array(
-          '#type' => 'checkbox',
-          '#title' => t('Transliterate') . '.',
-          '#default_value' => isset($settings[$name]['options']['transliterate']) && module_exists('transliteration')
-            ? $settings[$name]['options']['transliterate']
-            : 0,
-          '#description' => t('Transliterate @title', array('@title' => $field['title'])) . '.',
-          '#disabled' => !module_exists('transliteration'),
+          '#type'          => 'checkbox',
+          '#title'         => t('Transliterate'),
+          '#default_value' => isset($settings[$name]['options']['transliterate']) && module_exists('transliteration') ? $settings[$name]['options']['transliterate'] : 0,
+          '#description'   => t('Provides one-way string transliteration (romanization) and cleans the %title during upload by replacing unwanted characters.', array('%title' => t($field['title']))),
+          '#disabled'      => !module_exists('transliteration'),
         );
         );
 
 
         // Replacement patterns for field.
         // Replacement patterns for field.
-        $form['instance']['settings']['filefield_paths']['token_tree'] = array(
-          '#type' => 'fieldset',
-          '#title' => t('Replacement patterns'),
-          '#collapsible' => TRUE,
-          '#collapsed' => TRUE,
-          '#description' => theme('token_tree', array('token_types' => array('file', $entity_info['token type']))),
-          '#weight' => 10,
+        if (module_exists('token')) {
+          $form['instance']['settings']['filefield_paths']['token_tree'] = array(
+            '#theme'       => 'token_tree',
+            '#token_types' => array('file', $entity_info['token type']),
+            '#dialog'      => TRUE,
+            '#weight'      => 10,
+          );
+        }
+
+        // Redirect
+        $form['instance']['settings']['filefield_paths']['redirect'] = array(
+          '#type'          => 'checkbox',
+          '#title'         => t('Create Redirect'),
+          '#description'   => t('Create a redirect to the new location when a previously uploaded file is moved.'),
+          '#default_value' => isset($settings['redirect']) ? $settings['redirect'] : FALSE,
+          '#weight'        => 11,
         );
         );
+        if (!module_exists('redirect')) {
+          $form['instance']['settings']['filefield_paths']['redirect']['#disabled'] = TRUE;
+          $form['instance']['settings']['filefield_paths']['redirect']['#description'] .= '<br />' . t('Requires the <a href="https://drupal.org/project/redirect" target="_blank">Redirect</a> module.');
+        }
 
 
         // Retroactive updates.
         // Retroactive updates.
         $form['instance']['settings']['filefield_paths']['retroactive_update'] = array(
         $form['instance']['settings']['filefield_paths']['retroactive_update'] = array(
-          '#type' => 'checkbox',
-          '#title' => t('Retroactive update'),
-          '#description' => t('Move and rename previously uploaded files') . '.' .
-            '<br /> <strong style="color: #FF0000;">' . t('Warning') . ':</strong> ' .
-            t('This feature should only be used on developmental servers or with extreme caution') . '.',
-          '#weight' => 11,
+          '#type'        => 'checkbox',
+          '#title'       => t('Retroactive update'),
+          '#description' => t('Move and rename previously uploaded files.') . '<div>' . t('<strong class="warning">Warning:</strong> This feature should only be used on developmental servers or with extreme caution.') . '</div>',
+          '#weight'      => 12,
         );
         );
 
 
         // Active updating.
         // Active updating.
         $form['instance']['settings']['filefield_paths']['active_updating'] = array(
         $form['instance']['settings']['filefield_paths']['active_updating'] = array(
-          '#type' => 'checkbox',
-          '#title' => t('Active updating'),
+          '#type'          => 'checkbox',
+          '#title'         => t('Active updating'),
           '#default_value' => isset($settings['active_updating']) ? $settings['active_updating'] : FALSE,
           '#default_value' => isset($settings['active_updating']) ? $settings['active_updating'] : FALSE,
-          '#description' => t('Actively move and rename previously uploaded files as required') . '.' .
-            '<br /> <strong style="color: #FF0000;">' . t('Warning') . ':</strong> ' .
-            t('This feature should only be used on developmental servers or with extreme caution') . '.',
-          '#weight' => 12
+          '#description'   => t('Actively move and rename previously uploaded files as required.') . '<div>' . t('<strong class="warning">Warning:</strong> This feature should only be used on developmental servers or with extreme caution.') . '</div>',
+          '#weight'        => 13
         );
         );
       }
       }
     }
     }
@@ -131,14 +190,38 @@ function filefield_paths_form_alter(&$form, $form_state, $form_id) {
   }
   }
 }
 }
 
 
+/**
+ * Recursively set temporary upload location of all File (Field) Paths enabled
+ * managed file fields.
+ *
+ * @param $element
+ */
+function filefield_paths_temporary_upload_location(&$element) {
+  if (isset($element['#type']) && $element['#type'] == 'managed_file' && isset($element['#entity_type']) && isset($element['#field_name']) && isset($element['#bundle'])) {
+    $instance = field_info_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']);
+    if (isset($instance['settings']['filefield_paths_enabled']) && $instance['settings']['filefield_paths_enabled']) {
+      $element['#upload_location'] = variable_get('filefield_paths_temp_location', 'public://filefield_paths');
+    }
+    return;
+  }
+  foreach (element_children($element) as $child) {
+    filefield_paths_temporary_upload_location($element[$child]);
+  }
+}
+
+
 /**
 /**
  * Submit callback for File (Field) Paths settings form.
  * Submit callback for File (Field) Paths settings form.
+ *
+ * @param $form
+ * @param $form_state
  */
  */
 function filefield_paths_form_submit($form, &$form_state) {
 function filefield_paths_form_submit($form, &$form_state) {
   // Retroactive updates.
   // Retroactive updates.
-  if ($form_state['values']['instance']['settings']['filefield_paths']['retroactive_update']) {
-    filefield_paths_batch_update($form_state['values']['instance']);
-    batch_process($form_state['redirect']);
+  if ($form_state['values']['instance']['settings']['filefield_paths_enabled'] && $form_state['values']['instance']['settings']['filefield_paths']['retroactive_update']) {
+    if (filefield_paths_batch_update($form_state['values']['instance'])) {
+      batch_process($form_state['redirect']);
+    }
   }
   }
 }
 }
 
 
@@ -146,40 +229,58 @@ function filefield_paths_form_submit($form, &$form_state) {
  * Set batch process to update File (Field) Paths.
  * Set batch process to update File (Field) Paths.
  *
  *
  * @param $instance
  * @param $instance
+ *
+ * @return bool
  */
  */
 function filefield_paths_batch_update($instance) {
 function filefield_paths_batch_update($instance) {
-  $query = new EntityFieldQuery();
+  $query  = new EntityFieldQuery();
   $result = $query->entityCondition('entity_type', $instance['entity_type'])
   $result = $query->entityCondition('entity_type', $instance['entity_type'])
     ->entityCondition('bundle', array($instance['bundle']))
     ->entityCondition('bundle', array($instance['bundle']))
     ->fieldCondition($instance['field_name'])
     ->fieldCondition($instance['field_name'])
+    ->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT')
     ->execute();
     ->execute();
-  $objects = array_keys($result[$instance['entity_type']]);
+
+  // If there are no results, do not set a batch as there is nothing to process.
+  if (empty($result[$instance['entity_type']])) {
+    return FALSE;
+  }
+
+  $objects  = array_keys($result[$instance['entity_type']]);
+  $instance = field_info_instance($instance['entity_type'], $instance['field_name'], $instance['bundle']);
 
 
   // Create batch.
   // Create batch.
   $batch = array(
   $batch = array(
-    'title' => t('Updating File (Field) Paths'),
+    'title'      => t('Updating File (Field) Paths'),
     'operations' => array(
     'operations' => array(
       array('_filefield_paths_batch_update_process', array($objects, $instance))
       array('_filefield_paths_batch_update_process', array($objects, $instance))
     ),
     ),
   );
   );
   batch_set($batch);
   batch_set($batch);
+
+  return TRUE;
 }
 }
 
 
 /**
 /**
+ * Batch callback for File (Field) Paths retroactive updates.
+ *
+ * @param $objects
+ * @param $instance
+ * @param $context
  *
  *
+ * @throws FieldException
  */
  */
 function _filefield_paths_batch_update_process($objects, $instance, &$context) {
 function _filefield_paths_batch_update_process($objects, $instance, &$context) {
   if (!isset($context['sandbox']['progress'])) {
   if (!isset($context['sandbox']['progress'])) {
     $context['sandbox']['progress'] = 0;
     $context['sandbox']['progress'] = 0;
-    $context['sandbox']['max'] = count($objects);
-    $context['sandbox']['objects'] = $objects;
+    $context['sandbox']['max']      = count($objects);
+    $context['sandbox']['objects']  = $objects;
   }
   }
 
 
   // Process nodes by groups of 5.
   // Process nodes by groups of 5.
   $count = min(5, count($context['sandbox']['objects']));
   $count = min(5, count($context['sandbox']['objects']));
   for ($i = 1; $i <= $count; $i++) {
   for ($i = 1; $i <= $count; $i++) {
     // For each oid, load the object, update the files and save it.
     // For each oid, load the object, update the files and save it.
-    $oid = array_shift($context['sandbox']['objects']);
+    $oid    = array_shift($context['sandbox']['objects']);
     $entity = current(entity_load($instance['entity_type'], array($oid)));
     $entity = current(entity_load($instance['entity_type'], array($oid)));
 
 
     // Enable active updating if it isn't already enabled.
     // Enable active updating if it isn't already enabled.
@@ -189,8 +290,8 @@ function _filefield_paths_batch_update_process($objects, $instance, &$context) {
       field_update_instance($instance);
       field_update_instance($instance);
     }
     }
 
 
-    // Invoke File (Field) Paths implementation of hook_entity_update().
-    filefield_paths_entity_update($entity, $instance['entity_type']);
+    // Invoke field_attach_update().
+    field_attach_update($instance['entity_type'], $entity);
 
 
     // Restore active updating to it's previous state if necessary.
     // Restore active updating to it's previous state if necessary.
     if (!$active_updating) {
     if (!$active_updating) {
@@ -210,93 +311,161 @@ function _filefield_paths_batch_update_process($objects, $instance, &$context) {
 }
 }
 
 
 /**
 /**
- * Implements hook_entity_insert().
+ * Implements hook_field_storage_pre_insert().
+ *
+ * @param $entity_type
+ * @param $entity
  */
  */
-function filefield_paths_entity_insert($entity, $type) {
-  filefield_paths_entity_update($entity, $type);
+function filefield_paths_field_storage_pre_insert($entity_type, $entity) {
+  filefield_paths_field_storage_pre_update($entity_type, $entity);
 }
 }
 
 
 /**
 /**
- * Implements hook_entity_update().
+ * Implements hook_field_storage_pre_update().
+ *
+ * @param $entity_type
+ * @param $entity
  */
  */
-function filefield_paths_entity_update($entity, $type) {
+function filefield_paths_field_storage_pre_update($entity_type, $entity) {
   $field_types = _filefield_paths_get_field_types();
   $field_types = _filefield_paths_get_field_types();
-  $entity_info = entity_get_info($type);
-  $bundle_name = !empty($entity_info['entity keys']['bundle']) ? $entity->{$entity_info['entity keys']['bundle']} : $type;
+  $entity_info = entity_get_info($entity_type);
+  list(, , $bundle) = entity_extract_ids($entity_type, $entity);
   if ($entity_info['fieldable']) {
   if ($entity_info['fieldable']) {
-    foreach (field_info_fields($type, $bundle_name) as $field) {
+    foreach (field_info_fields() as $field) {
       if (in_array($field['type'], array_keys($field_types))) {
       if (in_array($field['type'], array_keys($field_types))) {
-        $files = array();
-        $instance = field_info_instance($type, $field['field_name'], $bundle_name);
-        if (isset($entity->{$field['field_name']})) {
+        $files    = array();
+        $instance = field_info_instance($entity_type, $field['field_name'], $bundle);
+        $enabled  = (isset($instance['settings']['filefield_paths_enabled']) && $instance['settings']['filefield_paths_enabled']) || !isset($instance['settings']['filefield_paths_enabled']);
+        if ($enabled && isset($entity->{$field['field_name']}) && is_array($entity->{$field['field_name']})) {
           foreach ($entity->{$field['field_name']} as $langcode => &$deltas) {
           foreach ($entity->{$field['field_name']} as $langcode => &$deltas) {
             foreach ($deltas as $delta => &$file) {
             foreach ($deltas as $delta => &$file) {
               // Prepare file.
               // Prepare file.
               if (function_exists($function = "{$field['module']}_field_load")) {
               if (function_exists($function = "{$field['module']}_field_load")) {
                 $items = array(array(&$file));
                 $items = array(array(&$file));
-                $function($type, array($entity), $field, array($instance), $langcode, $items, FIELD_LOAD_CURRENT);
+                $function($entity_type, array($entity), $field, array($instance), $langcode, $items, FIELD_LOAD_CURRENT);
               }
               }
               $files[] = &$file;
               $files[] = &$file;
             }
             }
-          }
-          // Invoke hook_filefield_paths_process_file().
-          foreach (module_implements('filefield_paths_process_file') as $module) {
-            if (function_exists($function = "{$module}_filefield_paths_process_file")) {
-              $function($type, $entity, $field, $instance, $langcode, $files);
+            // Invoke hook_filefield_paths_process_file().
+            foreach (module_implements('filefield_paths_process_file') as $module) {
+              if (function_exists($function = "{$module}_filefield_paths_process_file")) {
+                $function($entity_type, $entity, $field, $instance, $langcode, $files);
+              }
             }
             }
           }
           }
         }
         }
       }
       }
     }
     }
-
-    if (isset($entity->revision)) {
-      // Remember revision flag.
-      $revision = $entity->revision;
-      // Remove revision flag as long as fields already processed it, and no need
-      // to create new revision for moved files.
-      $entity->revision = FALSE;
-    }
-    // Save any changes back to the database.
-    field_attach_update($type, $entity);
-    if (isset($entity->revision)) {
-      // Restore revision flag so that other modules can process it if needed.
-      $entity->revision = $revision;
-    }
   }
   }
 }
 }
 
 
 /**
 /**
  * Implements hook_file_presave().
  * Implements hook_file_presave().
+ *
+ * @param $file
  */
  */
 function filefield_paths_file_presave($file) {
 function filefield_paths_file_presave($file) {
   // Store original filename in the database.
   // Store original filename in the database.
-  if (empty($file->origname)) {
+  if (empty($file->origname) && isset($file->filename)) {
     $file->origname = $file->filename;
     $file->origname = $file->filename;
   }
   }
 }
 }
 
 
+/**
+ * Creates a redirect for a moved File field.
+ *
+ * @param $source
+ * @param $path
+ *
+ * @throws Exception
+ */
+function _filefield_paths_create_redirect($source, $path) {
+  global $base_path;
+  watchdog('filefield_paths', 'Creating redirect from @source to @path', array(
+    '@source' => $source,
+    '@path'   => $path
+  ), WATCHDOG_DEBUG);
+
+  $redirect = new stdClass();
+  redirect_object_prepare($redirect);
+
+  $parsed_source = parse_url(file_create_url($source), PHP_URL_PATH);
+  $parsed_path   = parse_url(file_create_url($path), PHP_URL_PATH);
+
+  $redirect->source   = drupal_substr(urldecode($parsed_source), drupal_strlen($base_path));
+  $redirect->redirect = drupal_substr(urldecode($parsed_path), drupal_strlen($base_path));
+
+  // Check if the redirect exists before saving.
+  $hash = redirect_hash($redirect);
+  if (!redirect_load_by_hash($hash)) {
+    redirect_save($redirect);
+  }
+}
+
 /**
 /**
  * Run regular expression over all available text-based fields.
  * Run regular expression over all available text-based fields.
+ *
+ * @param $old
+ * @param $new
+ * @param $entity
  */
  */
 function _filefield_paths_replace_path($old, $new, $entity) {
 function _filefield_paths_replace_path($old, $new, $entity) {
-  // Build regular expression.
   $info = parse_url($old);
   $info = parse_url($old);
-  $info['path'] = !empty($info['path']) ? $info['path'] : '';
-  $absolute = str_replace("{$info['host']}{$info['path']}", '', file_create_url($old));
-  $relative = parse_url($absolute, PHP_URL_PATH);
-  $regex = str_replace('/', '\/', "({$absolute}|{$relative}|{$info['scheme']}://)(styles/.*?/{$info['scheme']}/|)({$info['host']}{$info['path']})");
+  if (isset($info['path'])) {
+    $info['host'] .= $info['path'];
+  }
+
+  // Generate all path prefix variations.
+  $prefixes = _filefield_paths_replace_path_get_prefixes($info['scheme'], TRUE);
+  $prefixes = implode('|', $prefixes);
+
+  // Generate all image style path variations.
+  $styles['raw']       = "styles/REGEX/{$info['scheme']}/";
+  $styles['urlencode'] = urlencode($styles['raw']);
+  foreach ($styles as &$style) {
+    $style = str_replace(array('/', 'REGEX'), array('\/', '(.*?)'), $style);
+  }
+  $styles = implode('|', $styles);
 
 
-  // Build replacement.
-  $info = parse_url($new);
-  $info['path'] = !empty($info['path']) ? $info['path'] : '';
-  $replacement = "_filefield_paths_replace_path_uri_scheme('\\1', '{$old}', '{$new}') . '\\2{$info['host']}{$info['path']}'";
+  // General all path variations.
+  $paths['raw']                = preg_quote($info['host'], '/');
+  $paths['urlencode']          = preg_quote(urlencode($info['host']), '/');
+  $paths['drupal_encode_path'] = preg_quote(drupal_encode_path($info['host']), '/');
+
+  $paths = implode('|', $paths);
+
+  // Newer versions of the Image module add an 8 character token which is
+  // required if the image style hasn't been generated yet.
+  $itok = '';
+  if (defined('IMAGE_DERIVATIVE_TOKEN')) {
+    $itok = '((?:[\?|&](?:\S+?&)*|(?:%3F|%26)(?:\S+?%26)*)' . IMAGE_DERIVATIVE_TOKEN . '(?:=|%3D)(\S{8}))*';
+  }
+
+  // Build regular expression pattern.
+  $pattern = "/({$prefixes})({$styles})*({$paths}){$itok}/";
+
+  // Create an anonymous function for the replacement via preg_replace_callback.
+  $callback = function ($matches) use ($new, $old) {
+    return filefield_paths_replace_path_callback($matches, $new, $old);
+  };
+  if (!$callback) {
+    watchdog('filefield_paths', 'Unable to create an anonymous function to find references of %old and replace with %new.', array(
+      '%old' => $old,
+      '%new' => $new,
+    ));
+    return;
+  }
 
 
   $fields = field_info_fields();
   $fields = field_info_fields();
   foreach ($fields as $name => $field) {
   foreach ($fields as $name => $field) {
     if ($field['module'] == 'text' && isset($entity->{$field['field_name']}) && is_array($entity->{$field['field_name']})) {
     if ($field['module'] == 'text' && isset($entity->{$field['field_name']}) && is_array($entity->{$field['field_name']})) {
       foreach ($entity->{$field['field_name']} as &$language) {
       foreach ($entity->{$field['field_name']} as &$language) {
         foreach ($language as &$item) {
         foreach ($language as &$item) {
-          $item['value'] = preg_replace("/$regex/e", $replacement, $item['value']);
+          foreach (array('value', 'summary') as $column) {
+            if (isset($item[$column])) {
+              $item[$column] = preg_replace_callback($pattern, $callback, $item[$column]);
+            }
+          }
         }
         }
       }
       }
     }
     }
@@ -304,49 +473,172 @@ function _filefield_paths_replace_path($old, $new, $entity) {
 }
 }
 
 
 /**
 /**
- * Helper function for File (Field) Paths URI updater regular expression.
+ * Helper function; Returns all variations of the file path prefix.
  *
  *
- * Determines what format the old URI prefix was and returns the new URI prefix
- * in the same format.
+ * @param            $scheme
+ * @param bool|FALSE $preg_quote
+ * @param bool|FALSE $reset
+ *
+ * @return mixed
  */
  */
-function _filefield_paths_replace_path_uri_scheme($prefix, $old, $new) {
-  switch (TRUE) {
-    case $prefix == file_uri_scheme($old) . '://':
-      return file_uri_scheme($new) . '://';
+function _filefield_paths_replace_path_get_prefixes($scheme, $preg_quote = FALSE, $reset = FALSE) {
+  $prefixes =& drupal_static(__FUNCTION__, array());
+
+  // Force clean urls on.
+  $clean_url = $GLOBALS['conf']['clean_url'];
+  $GLOBALS['conf']['clean_url'] = TRUE;
+
+  $id = $scheme . '::' . (string) $preg_quote;
+  if (!isset($prefixes[$id]) || $reset) {
+    $prefixes[$id]['uri']      = "{$scheme}://";
+    $prefixes[$id]['absolute'] = file_create_url($prefixes[$id]['uri']);
+    $prefixes[$id]['relative'] = parse_url($prefixes[$id]['absolute'], PHP_URL_PATH);
+    $prefixes[$id]['unclean']  = '?q=' . drupal_substr($prefixes[$id]['relative'], drupal_strlen(base_path()));
+
+    foreach ($prefixes[$id] as $key => $prefix) {
+      $prefixes[$id]["{$key}-urlencode"]          = urlencode($prefix);
+      $prefixes[$id]["{$key}-drupal_encode_path"] = drupal_encode_path($prefix);
+    }
 
 
-    case $prefix == file_create_url(file_uri_scheme($old) . '://'):
-      return file_create_url(file_uri_scheme($new) . '://');
+    if ($preg_quote) {
+      foreach ($prefixes[$id] as $key => $prefix) {
+        $prefixes[$id][$key] = preg_quote($prefixes[$id][$key], '/');
+      }
+    }
+  }
+
+  // Restore clean url settings.
+  $GLOBALS['conf']['clean_url'] = $clean_url;
 
 
-    case $prefix == parse_url(file_create_url(file_uri_scheme($old) . '://'), PHP_URL_PATH):
-      return parse_url(file_create_url(file_uri_scheme($new) . '://'), PHP_URL_PATH);
+  return $prefixes[$id];
+}
+
+/**
+ * Callback for regex string replacement functionality.
+ *
+ * @param $matches
+ * @param $new
+ * @param $old
+ *
+ * @return string
+ */
+function filefield_paths_replace_path_callback($matches, $new, $old) {
+  $prefix = $matches[1];
+  $styles = $matches[2];
+  $query  = isset($matches[6]) ? $matches[6] : '';
+
+  // Get file path info for old file.
+  $old_info = parse_url($old);
+  if (isset($old_info['path'])) {
+    $old_info['host'] .= $old_info['path'];
   }
   }
 
 
-  return $prefix;
+  // Determine the file path variation type/modifier.
+  $old_prefixes = _filefield_paths_replace_path_get_prefixes($old_info['scheme']);
+  $modifier     = NULL;
+  foreach ($old_prefixes as $key => $old_prefix) {
+    if ($prefix == $old_prefix) {
+      $parts    = explode('-', $key);
+      $modifier = isset($parts[1]) ? $parts[1] : NULL;
+      break;
+    }
+  }
+
+  // Get file path info for new file.
+  $new_info = parse_url($new);
+  if (isset($new_info['path'])) {
+    $new_info['host'] .= $new_info['path'];
+  }
+
+  // Replace prefix.
+  $prefixes = _filefield_paths_replace_path_get_prefixes($new_info['scheme']);
+  if (isset($key) && isset($prefixes[$key])) {
+    $prefix = $prefixes[$key];
+  }
+
+  // Replace styles directory.
+  if (!empty($styles)) {
+    $styles = str_replace($old_info['scheme'], $new_info['scheme'], $styles);
+
+    // Newer versions of the Image module add an 8 character token which is
+    // required if the image style hasn't been generated yet.
+    if (defined('IMAGE_DERIVATIVE_TOKEN') && isset($matches[7])) {
+      $image_style = !empty($matches[3]) ? $matches[3] : $matches[4];
+      // Only replace the token if the old one was valid.
+      if ($matches[7] == image_style_path_token($image_style, $old)) {
+        $query = substr_replace($query, image_style_path_token($image_style, $new), -strlen($matches[7]));
+      }
+    }
+  }
+
+  // Replace path.
+  $path = $new_info['host'];
+  if (!is_null($modifier) && function_exists($modifier)) {
+    $path = call_user_func($modifier, $path);
+  }
+
+  return $prefix . $styles . $path . $query;
 }
 }
 
 
 /**
 /**
  * Process and cleanup strings.
  * Process and cleanup strings.
+ *
+ * @param       $value
+ * @param       $data
+ * @param array $settings
+ *
+ * @return mixed|string
  */
  */
 function filefield_paths_process_string($value, $data, $settings = array()) {
 function filefield_paths_process_string($value, $data, $settings = array()) {
-  $transliterate = module_exists('transliteration') && isset($settings['transliterate']) && $settings['transliterate'];
-  $pathauto = module_exists('pathauto') && isset($settings['pathauto']) && $settings['pathauto'] == TRUE;
+  $transliterate  = module_exists('transliteration') && isset($settings['transliterate']) && $settings['transliterate'];
+  $pathauto       = module_exists('pathauto') && isset($settings['pathauto']) && $settings['pathauto'] == TRUE;
+  $remove_slashes = !empty($settings['slashes']);
+
   if ($pathauto == TRUE) {
   if ($pathauto == TRUE) {
     module_load_include('inc', 'pathauto');
     module_load_include('inc', 'pathauto');
   }
   }
 
 
+  // If '/' is to be removed from tokens, token replacement need to happen after
+  // splitting the paths to subdirs, otherwise tokens containing '/' will be
+  // part of the final path.
+  if (!$remove_slashes) {
+    $value = token_replace($value, $data, array('clear' => TRUE));
+  }
   $paths = explode('/', $value);
   $paths = explode('/', $value);
-  foreach ($paths as &$path) {
-
-    // Process string tokens.
-    $path = token_replace($path, $data, array('clear' => TRUE));
 
 
-    // Cleanup with pathauto.
+  foreach ($paths as $i => &$path) {
+    if ($remove_slashes) {
+      $path = token_replace($path, $data, array('clear' => TRUE));
+    }
     if ($pathauto == TRUE) {
     if ($pathauto == TRUE) {
-      $path_parts = explode('.', $path);
-      foreach ($path_parts as &$path_part) {
-        $path_part = pathauto_cleanstring($path_part);
+      if ('file_name' == $settings['context'] && count($paths) == $i + 1) {
+        $pathinfo             = pathinfo($path);
+        $basename             = drupal_basename($path);
+        $extension            = preg_match('/\.[^.]+$/', $basename, $matches) ? $matches[0] : NULL;
+        $pathinfo['filename'] = !is_null($extension) ? drupal_substr($basename, 0, drupal_strlen($basename) - drupal_strlen($extension)) : $basename;
+
+        if ($remove_slashes) {
+          $path = '';
+          if (!empty($pathinfo['dirname']) && $pathinfo['dirname'] !== '.') {
+            $path .= $pathinfo['dirname'] . '/';
+          }
+          $path .= $pathinfo['filename'];
+          $path = pathauto_cleanstring($path);
+          if (!empty($pathinfo['extension'])) {
+            $path .= '.' . pathauto_cleanstring($pathinfo['extension']);
+          }
+          $path = str_replace('/', '', $path);
+        }
+        else {
+          $path = str_replace($pathinfo['filename'], pathauto_cleanstring($pathinfo['filename']), $path);
+        }
+      }
+      else {
+        $path = pathauto_cleanstring($path);
       }
       }
-      $path = implode('.', $path_parts);
+    }
+    elseif ($remove_slashes) {
+      $path = str_replace('/', '', $path);
     }
     }
 
 
     // Transliterate string.
     // Transliterate string.
@@ -363,7 +655,11 @@ function filefield_paths_process_string($value, $data, $settings = array()) {
 }
 }
 
 
 /**
 /**
+ * Provides a list of all available field types for use with File (Field) Paths.
+ *
+ * @param bool|FALSE $reset
  *
  *
+ * @return array
  */
  */
 function _filefield_paths_get_field_types($reset = FALSE) {
 function _filefield_paths_get_field_types($reset = FALSE) {
   $field_types = &drupal_static(__FUNCTION__);
   $field_types = &drupal_static(__FUNCTION__);
@@ -372,7 +668,7 @@ function _filefield_paths_get_field_types($reset = FALSE) {
     $field_types = module_invoke_all('filefield_paths_field_type_info');
     $field_types = module_invoke_all('filefield_paths_field_type_info');
     $field_types = array_flip($field_types);
     $field_types = array_flip($field_types);
     foreach (array_keys($field_types) as $type) {
     foreach (array_keys($field_types) as $type) {
-      $info = field_info_field_types($type);
+      $info               = field_info_field_types($type);
       $field_types[$type] = array(
       $field_types[$type] = array(
         'label' => $info['label']
         'label' => $info['label']
       );
       );
@@ -381,3 +677,4 @@ function _filefield_paths_get_field_types($reset = FALSE) {
 
 
   return $field_types;
   return $field_types;
 }
 }
+

+ 72 - 0
sites/all/modules/filefield_paths/filefield_paths.tokens.inc

@@ -0,0 +1,72 @@
+<?php
+
+/**
+ * @file
+ * Tokens for the File (Field) Paths module.
+ */
+
+/**
+ * Implements hook_token_info().
+ *
+ * @return mixed
+ */
+function filefield_paths_token_info() {
+  $info['tokens']['file']['ffp-name-only']          = array(
+    'name'        => t("File name"),
+    'description' => t("File name without extension."),
+  );
+  $info['tokens']['file']['ffp-name-only-original'] = array(
+    'name'        => t("File name - original"),
+    'description' => t("File name without extension - original."),
+  );
+  $info['tokens']['file']['ffp-extension-original'] = array(
+    'name'        => t("File extension - original"),
+    'description' => t("File extension - original."),
+  );
+
+  return $info;
+}
+
+/**
+ * Implements hook_tokens().
+ *
+ * @param       $type
+ * @param       $tokens
+ * @param array $data
+ *
+ * @return array
+ */
+function filefield_paths_tokens($type, $tokens, array $data = array()) {
+  $url_options = array('absolute' => TRUE);
+  if (isset($language)) {
+    $url_options['language'] = $language;
+  }
+
+  $replacements = array();
+
+  if ($type == 'file' && !empty($data['file'])) {
+    $file = $data['file'];
+
+    foreach ($tokens as $name => $original) {
+      switch ($name) {
+        case 'ffp-name-only':
+          $basename                = drupal_basename($file->filename);
+          $extension               = preg_match('/\.[^.]+$/', $basename, $matches) ? $matches[0] : NULL;
+          $replacements[$original] = !is_null($extension) ? drupal_substr($basename, 0, drupal_strlen($basename) - drupal_strlen($extension)) : $basename;
+          break;
+
+        case 'ffp-name-only-original':
+          $basename                = drupal_basename($file->origname);
+          $extension               = preg_match('/\.[^.]+$/', $basename, $matches) ? $matches[0] : NULL;
+          $replacements[$original] = !is_null($extension) ? drupal_substr($basename, 0, drupal_strlen($basename) - drupal_strlen($extension)) : $basename;
+          break;
+
+        case 'ffp-extension-original':
+          $replacements[$original] = preg_match('/[^.]+$/', drupal_basename($file->origname), $matches) ? $matches[0] : NULL;
+          break;
+      }
+    }
+  }
+
+  return $replacements;
+}

+ 57 - 0
sites/all/modules/filefield_paths/filefield_paths.variable.inc

@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * @file
+ * Contains Variable functions for the File (Field) Paths module.
+ */
+
+/**
+ * Implements hook_variable_info().
+ *
+ * @return mixed
+ */
+function filefield_paths_variable_info() {
+  $variables['filefield_paths_temp_location'] = array(
+    'title'             => t('Temporary file location'),
+    'type'              => 'string',
+    'default'           => 'public://filefield_paths',
+    'description'       => t('The location that unprocessed files will be uploaded priot to being processed by File (Field) Paths.<br />It is recommended that you use the temporary file system (temporary://) if your server configuration allows for that.'),
+    'validate callback' => 'filefield_paths_variable_temp_location_validate',
+    'group'             => 'filefield_paths',
+  );
+
+  return $variables;
+}
+
+/**
+ * Validate callback for 'Temporary file location' variable.
+ *
+ * @param $element
+ */
+function filefield_paths_variable_temp_location_validate($element) {
+  // Add FAPI element keys for standard validation callback.
+  $element['#parents'] = array('filefield_paths_temp_location');
+  $element['#value'] = $element['value'];
+
+  // Pass element through standard validation callback.
+  module_load_include('admin.inc', 'filefield_paths');
+  filefield_paths_settings_form_temp_location_validate($element);
+}
+
+/**
+ * Implements hook_variable_group_info().
+ *
+ * @return mixed
+ */
+function filefield_paths_variable_group_info() {
+  $groups['filefield_paths'] = array(
+    'title'       => t('File (Field) Paths'),
+    'description' => t('File (Field) Paths settings.'),
+    'access'      => 'administer site configuration',
+    'path'        => array(
+      'admin/config/media/file-system/filefield-paths'
+    ),
+  );
+
+  return $groups;
+}

+ 18 - 2
sites/all/modules/filefield_paths/modules/features.inc

@@ -1,16 +1,21 @@
 <?php
 <?php
+
 /**
 /**
  * @file
  * @file
  * Features module integration.
  * Features module integration.
  */
  */
 
 
 /**
 /**
- * Implements hook_features_pipe_field_alter().
+ * Implements hook_features_pipe_field_instance_alter().
  *
  *
  * This determines whether exported fields contain File (Field) Paths settings
  * This determines whether exported fields contain File (Field) Paths settings
  * and if so adds File (Field) Paths as a dependency.
  * and if so adds File (Field) Paths as a dependency.
+ *
+ * @param $pipe
+ * @param $data
+ * @param $export
  */
  */
-function filefield_paths_features_pipe_field_alter(&$pipe, $data, &$export) {
+function filefield_paths_features_pipe_field_instance_alter(&$pipe, $data, &$export) {
   foreach ($data as $field_identifier) {
   foreach ($data as $field_identifier) {
     list($entity_type, $bundle_name, $field_name) = explode('-', $field_identifier);
     list($entity_type, $bundle_name, $field_name) = explode('-', $field_identifier);
     $instance = field_info_instance($entity_type, $field_name, $bundle_name);
     $instance = field_info_instance($entity_type, $field_name, $bundle_name);
@@ -19,3 +24,14 @@ function filefield_paths_features_pipe_field_alter(&$pipe, $data, &$export) {
     }
     }
   }
   }
 }
 }
+
+/**
+ * Implements hook_features_pipe_field_alter().
+ *
+ * @param $pipe
+ * @param $data
+ * @param $export
+ */
+function filefield_paths_features_pipe_field_alter(&$pipe, $data, &$export) {
+  filefield_paths_features_pipe_field_instance_alter($pipe, $data, $export);
+}

+ 4 - 1
sites/all/modules/filefield_paths/modules/file.inc

@@ -1,11 +1,14 @@
 <?php
 <?php
+
 /**
 /**
  * @file
  * @file
  * File module integration.
  * File module integration.
  */
  */
 
 
 /**
 /**
- * Implements hook_filefield_paths_filed_type_info() on behalf of file.module.
+ * Implements hook_filefield_paths_field_type_info() on behalf of file.module.
+ *
+ * @return array
  */
  */
 function file_filefield_paths_field_type_info() {
 function file_filefield_paths_field_type_info() {
   return array('file');
   return array('file');

+ 91 - 42
sites/all/modules/filefield_paths/modules/filefield_paths.inc

@@ -1,4 +1,5 @@
 <?php
 <?php
+
 /**
 /**
  * @file
  * @file
  * File (Field) Paths module integration.
  * File (Field) Paths module integration.
@@ -6,31 +7,35 @@
 
 
 /**
 /**
  * Implements hook_filefield_paths_field_settings().
  * Implements hook_filefield_paths_field_settings().
+ *
+ * @param $field
+ * @param $instance
+ *
+ * @return array
  */
  */
-function filefield_paths_filefield_paths_field_settings() {
+function filefield_paths_filefield_paths_field_settings($field, $instance) {
   return array(
   return array(
     'file_path' => array(
     'file_path' => array(
       'title' => 'File path',
       'title' => 'File path',
-      'sql' => 'filepath',
-
-      'form' => array(
+      'form'  => array(
         'value' => array(
         'value' => array(
-          '#type' => 'textfield',
-          '#title' => t('File path'),
-          '#maxlength' => 512,
-          '#size' => 128,
+          '#type'             => 'textfield',
+          '#title'            => t('File path'),
+          '#maxlength'        => 512,
+          '#size'             => 128,
+          '#element_validate' => array('_file_generic_settings_file_directory_validate'),
+          '#default_value'    => $instance['settings']['file_directory'],
         ),
         ),
       ),
       ),
     ),
     ),
-
     'file_name' => array(
     'file_name' => array(
       'title' => 'File name',
       'title' => 'File name',
-      'sql' => 'filename',
-
-      'form' => array(
+      'form'  => array(
         'value' => array(
         'value' => array(
-          '#type' => 'textfield',
-          '#title' => t('File name'),
+          '#type'          => 'textfield',
+          '#title'         => t('File name'),
+          '#maxlength'     => 512,
+          '#size'          => 128,
           '#default_value' => '[file:ffp-name-only-original].[file:ffp-extension-original]',
           '#default_value' => '[file:ffp-name-only-original].[file:ffp-extension-original]',
         ),
         ),
       ),
       ),
@@ -40,42 +45,86 @@ function filefield_paths_filefield_paths_field_settings() {
 
 
 /**
 /**
  * Implements hook_filefield_paths_process_file().
  * Implements hook_filefield_paths_process_file().
+ *
+ * @param $type
+ * @param $entity
+ * @param $field
+ * @param $instance
+ * @param $langcode
+ * @param $items
  */
  */
 function filefield_paths_filefield_paths_process_file($type, $entity, $field, $instance, $langcode, &$items) {
 function filefield_paths_filefield_paths_process_file($type, $entity, $field, $instance, $langcode, &$items) {
-  $settings = $instance['settings']['filefield_paths'];
-  foreach ($items as &$file) {
-    if ($file['timestamp'] == REQUEST_TIME || $settings['active_updating']) {
-      $token_data = array(
-        'file' => (object) $file,
-        $type => $entity
-      );
+  if (isset($instance['settings']['filefield_paths'])) {
+    $settings = $instance['settings']['filefield_paths'];
+
+    // Check that the destination is writeable.
+    $wrappers = file_get_stream_wrappers(STREAM_WRAPPERS_WRITE);
+    foreach ($items as &$file) {
+      $source_scheme = file_uri_scheme($file['uri']);
+      $temporary_scheme = file_uri_scheme(variable_get('filefield_paths_temp_location', 'public://filefield_paths'));
+      $destination_scheme = $field['settings']['uri_scheme'];
+      if (in_array($source_scheme, array($temporary_scheme, $destination_scheme)) && !empty($wrappers[$destination_scheme])) {
+        // Process file if this is a new entity, 'Active updating' is set or
+        // file wasn't previously attached to the entity.
+        if (isset($entity->original) && empty($settings['active_updating']) && !empty($entity->original->{$field['field_name']}[$langcode])) {
+          foreach ($entity->original->{$field['field_name']}[$langcode] as $original_file) {
+            if ($original_file['fid'] == $file['fid']) {
+              continue(2);
+            }
+          }
+        }
+
+        $token_data = array(
+          'file' => (object) $file,
+          $type  => $entity
+        );
 
 
-      // Copy the original file for comparision purposes.
-      $old_file = $file;
+        // Copy the original file for comparison purposes.
+        $old_file = $file;
 
 
-      // Process filename.
-      $file['filename'] = !empty($settings['file_name']['value'])
-        ? filefield_paths_process_string($settings['file_name']['value'], $token_data, $settings['file_name']['options'])
-        : $file['filename'];
+        // Process filename.
+        $settings['file_name']['options']['context'] = 'file_name';
+        $file['filename']                            = !empty($settings['file_name']['value']) ? filefield_paths_process_string($settings['file_name']['value'], $token_data, $settings['file_name']['options']) : $file['filename'];
 
 
-      // Process filepath.
-      $file['uri'] = "{$field['settings']['uri_scheme']}://" . filefield_paths_process_string($settings['file_path']['value'] . "/{$file['filename']}", $token_data, $settings['file_path']['options']);
+        // Process filepath.
+        $settings['file_path']['options']['context'] = 'file_path';
+        $path                                        = filefield_paths_process_string($settings['file_path']['value'], $token_data, $settings['file_path']['options']);
+        $file['uri']                                 = file_stream_wrapper_uri_normalize("{$destination_scheme}://{$path}/{$file['filename']}");
+
+        // Ensure file uri is no more than 255 characters.
+        if (drupal_strlen($file['uri']) > 255) {
+          watchdog('filefield_paths', 'File path was truncated.', array(), WATCHDOG_INFO);
+          $pathinfo    = pathinfo($file['uri']);
+          $file['uri'] = drupal_substr($file['uri'], 0, 254 - drupal_strlen($pathinfo['extension'])) . ".{$pathinfo['extension']}";
+        }
 
 
-      // Finalize file if necessary.
-      if ($file !== $old_file) {
-        if (file_prepare_directory(drupal_dirname($file['uri']), FILE_CREATE_DIRECTORY) && file_move((object) $old_file, $file['uri'])) {
-          // Process regular expression.
-          _filefield_paths_replace_path($old_file['uri'], $file['uri'], $entity);
+        // Finalize file if necessary.
+        if ($file !== $old_file) {
+          $dirname = drupal_dirname($file['uri']);
+          if (file_prepare_directory($dirname, FILE_CREATE_DIRECTORY) && $new_file = file_move((object) $old_file, $file['uri'])) {
+            // Process regular expression.
+            _filefield_paths_replace_path($old_file['uri'], $file['uri'], $entity);
 
 
-          // Remove any old empty directories.
-          $scheme = file_uri_scheme($old_file['uri']);
-          $paths = explode('/', str_replace("{$scheme}://", '', drupal_dirname($old_file['uri'])));
-          while ($paths) {
-            if (@drupal_rmdir("{$scheme}://" . implode('/', $paths)) == TRUE) {
-              array_pop($paths);
-              continue;
+            // Create redirect from old location.
+            if (module_exists('redirect') && !empty($settings['redirect']) && $settings['active_updating']) {
+              _filefield_paths_create_redirect($old_file['uri'], $new_file->uri);
             }
             }
-            break;
+
+            // Remove any old empty directories.
+            $paths  = explode('/', str_replace("{$source_scheme}://", '', drupal_dirname($old_file['uri'])));
+            while ($paths) {
+              if (@drupal_rmdir("{$source_scheme}://" . implode('/', $paths)) == TRUE) {
+                array_pop($paths);
+                continue;
+              }
+              break;
+            }
+          }
+          else {
+            watchdog('filefield_paths', 'The file %old could not be moved to the destination of %new. Ensure your permissions are set correctly.', array(
+              '%old' => $old_file['uri'],
+              '%new' => $file['uri'],
+            ));
           }
           }
         }
         }
       }
       }

+ 17 - 0
sites/all/modules/filefield_paths/modules/image.inc

@@ -1,4 +1,5 @@
 <?php
 <?php
+
 /**
 /**
  * @file
  * @file
  * Image module integration.
  * Image module integration.
@@ -6,7 +7,23 @@
 
 
 /**
 /**
  * Implements hook_filefield_paths_field_type_info() on behalf of image.module.
  * Implements hook_filefield_paths_field_type_info() on behalf of image.module.
+ *
+ * @return array
  */
  */
 function image_filefield_paths_field_type_info() {
 function image_filefield_paths_field_type_info() {
   return array('image');
   return array('image');
 }
 }
+
+/**
+ * Implements hook_menu_alter().
+ *
+ * @param $items
+ */
+function filefield_paths_menu_alter(&$items) {
+  // Workaround for issue with 'temporary://' image styles not being generated
+  // correctly in Drupal core Image module.
+  // @see https://www.drupal.org/node/2560139
+  if (!isset($items['system/temporary/styles/%image_style']) && isset($items['system/files/styles/%image_style'])) {
+    $items['system/temporary/styles/%image_style'] = $items['system/files/styles/%image_style'];
+  }
+}

+ 0 - 63
sites/all/modules/filefield_paths/modules/token.inc

@@ -1,63 +0,0 @@
-<?php
-/**
- * @file
- * Token module integration.
- */
-
-/**
- * Implements hook_token_info().
- */
-function filefield_paths_token_info() {
-  $info['tokens']['file']['ffp-name-only'] = array(
-    'name' => t("File name"),
-    'description' => t("File name without extension."),
-  );
-  $info['tokens']['file']['ffp-name-only-original'] = array(
-    'name' => t("File name - original"),
-    'description' => t("File name without extension - original."),
-  );
-  $info['tokens']['file']['ffp-extension-original'] = array(
-    'name' => t("File extension - original"),
-    'description' => t("File extension - original."),
-  );
-
-  return $info;
-}
-
-/**
- * Implements hook_tokens().
- */
-function filefield_paths_tokens($type, $tokens, array $data = array(), array $options = array()) {
-  $url_options = array('absolute' => TRUE);
-  if (isset($language)) {
-    $url_options['language'] = $language;
-  }
-  $sanitize = !empty($options['sanitize']);
-
-  $replacements = array();
-
-  if ($type == 'file' && !empty($data['file'])) {
-    $file = $data['file'];
-
-    foreach ($tokens as $name => $original) {
-      switch ($name) {
-        case 'ffp-name-only':
-          $info = pathinfo($file->filename);
-          $replacements[$original] = $info['filename'];
-          break;
-
-        case 'ffp-name-only-original':
-          $info = pathinfo($file->origname);
-          $replacements[$original] = $info['filename'];
-          break;
-
-        case 'ffp-extension-original':
-          $info = pathinfo($file->origname);
-          $replacements[$original] = $info['extension'];
-          break;
-      }
-    }
-  }
-
-  return $replacements;
-}

+ 3 - 0
sites/all/modules/filefield_paths/modules/video.inc

@@ -1,4 +1,5 @@
 <?php
 <?php
+
 /**
 /**
  * @file
  * @file
  * Video module integration.
  * Video module integration.
@@ -6,6 +7,8 @@
 
 
 /**
 /**
  * Implements hook_filefield_paths_field_type_info() on behalf of video.module.
  * Implements hook_filefield_paths_field_type_info() on behalf of video.module.
+ *
+ * @return array
  */
  */
 function video_filefield_paths_field_type_info() {
 function video_filefield_paths_field_type_info() {
   return array('video');
   return array('video');

+ 327 - 0
sites/all/modules/filefield_paths/tests/filefield_paths.general.test

@@ -0,0 +1,327 @@
+<?php
+
+/**
+ * @file
+ * Tests for the File (Field) Paths module.
+ */
+
+/**
+ * Class FileFieldPathsGeneralTestCase
+ */
+class FileFieldPathsGeneralTestCase extends FileFieldPathsTestCase {
+  /**
+   * @inheritdoc
+   */
+  public static function getInfo() {
+    return array(
+      'name'        => 'General functionality',
+      'description' => 'Test general functionality.',
+      'group'       => 'File (Field) Paths',
+    );
+  }
+
+  /**
+   * Test that the File (Field) Paths UI works as expected.
+   */
+  public function testAddField() {
+    // Create a File field.
+    $field_name        = drupal_strtolower($this->randomName());
+    $instance_settings = array('file_directory' => "fields/{$field_name}");
+    $this->createFileField($field_name, $this->content_type, array(), $instance_settings);
+
+    // Ensure File (Field) Paths settings are present.
+    $this->drupalGet("admin/structure/types/manage/{$this->content_type}/fields/{$field_name}");
+    $this->assertText('Enable File (Field) Paths?', t('File (Field) Path settings are present.'));
+
+    // Ensure that 'Enable File (Field) Paths?' is a direct sibling of
+    // 'File (Field) Path settings'.
+    $element = $this->xpath('//div[contains(@class, :class)]/following-sibling::*[1]/@id', array(':class' => 'form-item-instance-settings-filefield-paths-enabled'));
+    $this->assert(isset($element[0]) && 'edit-instance-settings-filefield-paths' == (string) $element[0], t('Enable checkbox is next to settings fieldset.'));
+
+    // Ensure that the File path used the File directory as it's default value.
+    $this->assertFieldByName('instance[settings][filefield_paths][file_path][value]', "fields/{$field_name}");
+  }
+
+  /**
+   * Test File (Field) Paths works as normal when no file uploaded.
+   */
+  public function testNoFile() {
+    // Create a File field.
+    $field_name                                                 = drupal_strtolower($this->randomName());
+    $instance_settings['filefield_paths']['file_path']['value'] = 'node/[node:nid]';
+    $instance_settings['filefield_paths']['file_name']['value'] = '[node:nid].[file:ffp-extension-original]';
+    $this->createFileField($field_name, $this->content_type, array(), $instance_settings);
+
+    // Create a node without a file attached.
+    $this->drupalCreateNode(array('type' => $this->content_type));
+  }
+
+  /**
+   * Test a basic file upload with File (Field) Paths.
+   */
+  public function testUploadFile() {
+    $langcode = LANGUAGE_NONE;
+
+    // Create a File field with 'node/[node:nid]' as the File path and
+    // '[node:nid].[file:ffp-extension-original]' as the File name.
+    $field_name                                                 = drupal_strtolower($this->randomName());
+    $instance_settings['filefield_paths']['file_path']['value'] = 'node/[node:nid]';
+    $instance_settings['filefield_paths']['file_name']['value'] = '[node:nid].[file:ffp-extension-original]';
+    $this->createFileField($field_name, $this->content_type, array(), $instance_settings);
+
+    $schemes = array('public', 'private');
+    foreach ($schemes as $scheme) {
+      // Set the field URI scheme.
+      $this->drupalPost("admin/structure/types/manage/{$this->content_type}/fields/{$field_name}", array('field[settings][uri_scheme]' => $scheme), t('Save settings'));
+
+      // Upload a file to a node.
+      $test_file = $this->getTestFile('text');
+      $this->drupalGet("node/add/{$this->content_type}");
+      $edit['title'] = $this->randomName();
+      $edit["files[{$field_name}_{$langcode}_0]"] = $test_file->uri;
+      $this->drupalPost(NULL, $edit, t('Upload'));
+
+      // Ensure that the file was put into the Temporary file location.
+      $temp_location = variable_get('filefield_paths_temp_location', 'public://filefield_paths');
+      $this->assertRaw(file_create_url("{$temp_location}/{$test_file->filename}"), t('File has been uploaded to the temporary file location.'));
+
+      // Save the node.
+      $this->drupalPost(NULL, array(), t('Save'));
+
+      // Get created Node ID.
+      $matches = array();
+      preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches);
+      $nid = $matches[1];
+
+      // Ensure that the File path has been processed correctly.
+      $uri = file_create_url("{$scheme}://node/{$nid}/{$nid}.txt");
+      $this->assertRaw($uri, t('The File path has been processed correctly.'));
+
+      // Delete the node so we can change the URI scheme.
+      node_delete($nid);
+    }
+  }
+
+  /**
+   * Tests a multivalue file upload with File (Field) Paths.
+   */
+  public function testUploadFileMultivalue() {
+    $langcode = LANGUAGE_NONE;
+
+    // Create a multivalue File field with 'node/[node:nid]' as the File path
+    // and '[file:fid].txt' as the File name.
+    $field_name                                                 = drupal_strtolower($this->randomName());
+    $field_settings['cardinality']                              = FIELD_CARDINALITY_UNLIMITED;
+    $instance_settings['filefield_paths']['file_path']['value'] = 'node/[node:nid]';
+    $instance_settings['filefield_paths']['file_name']['value'] = '[file:fid].txt';
+    $this->createFileField($field_name, $this->content_type, $field_settings, $instance_settings);
+
+    // Create a node with three (3) test files.
+    $text_files = $this->drupalGetTestFiles('text');
+    $this->drupalGet("node/add/{$this->content_type}");
+    $this->drupalPost(NULL, array("files[{$field_name}_{$langcode}_0]" => drupal_realpath($text_files[0]->uri)), t('Upload'));
+    $this->drupalPost(NULL, array("files[{$field_name}_{$langcode}_1]" => drupal_realpath($text_files[1]->uri)), t('Upload'));
+    $edit = array(
+      'title'                              => $this->randomName(),
+      "files[{$field_name}_{$langcode}_2]" => drupal_realpath($text_files[1]->uri),
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    // Get created Node ID.
+    $matches = array();
+    preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches);
+    $nid = $matches[1];
+
+    // Ensure that the File path has been processed correctly.
+    $this->assertRaw("{$this->public_files_directory}/node/{$nid}/1.txt", t('The first File path has been processed correctly.'));
+    $this->assertRaw("{$this->public_files_directory}/node/{$nid}/2.txt", t('The second File path has been processed correctly.'));
+    $this->assertRaw("{$this->public_files_directory}/node/{$nid}/3.txt", t('The third File path has been processed correctly.'));
+  }
+
+  /**
+   * Test File (Field) Paths with a very long path.
+   */
+  public function testLongPath() {
+    // Create a File field with 'node/[random:hash:sha256]' as the File path.
+    $field_name                                                 = drupal_strtolower($this->randomName());
+    $instance_settings['filefield_paths']['file_path']['value'] = 'node/[random:hash:sha512]/[random:hash:sha512]';
+    $this->createFileField($field_name, $this->content_type, array(), $instance_settings);
+
+    // Create a node with a test file.
+    $test_file = $this->getTestFile('text');
+    $nid       = $this->uploadNodeFile($test_file, $field_name, $this->content_type);
+
+    // Ensure file path is no more than 255 characters.
+    $node = node_load($nid, NULL, TRUE);
+    $this->assert(drupal_strlen($node->{$field_name}[LANGUAGE_NONE][0]['uri']) <= 255, t('File path is no more than 255 characters'));
+  }
+
+  /**
+   * Test File (Field) Paths on a programmatically added file.
+   */
+  public function testProgrammaticAttach() {
+    // Create a File field with 'node/[node:nid]' as the File path and
+    // '[node:nid].[file:ffp-extension-original]' as the File name.
+    $field_name                                                 = drupal_strtolower($this->randomName());
+    $instance_settings['filefield_paths']['file_path']['value'] = 'node/[node:nid]';
+    $instance_settings['filefield_paths']['file_name']['value'] = '[node:nid].[file:ffp-extension-original]';
+    $this->createFileField($field_name, $this->content_type, array(), $instance_settings);
+
+    // Create a node without an attached file.
+    $node = $this->drupalCreateNode(array('type' => $this->content_type));
+
+    // Create a file object.
+    $test_file = $this->getTestFile('text');
+
+    $file           = new stdClass();
+    $file->fid      = NULL;
+    $file->uri      = $test_file->uri;
+    $file->filename = basename($file->uri);
+    $file->filemime = file_get_mimetype($file->uri);
+    $file->uid      = $GLOBALS['user']->uid;
+    $file->status   = FILE_STATUS_PERMANENT;
+    $file->display  = TRUE;
+    file_save($file);
+
+    // Adjust timestamp to simulate real-world experience.
+    $file->timestamp = REQUEST_TIME - 60;
+
+    // Attach the file to the node.
+    $node->{$field_name}[LANGUAGE_NONE][0] = (array) $file;
+    node_save($node);
+
+    // Ensure that the File path has been processed correctly.
+    $node = node_load($node->nid, NULL, TRUE);
+    $this->assertEqual("public://node/{$node->nid}/{$node->nid}.txt", $node->{$field_name}[LANGUAGE_NONE][0]['uri'], t('The File path has been processed correctly.'));
+  }
+
+  /**
+   * Test File (Field) Paths slashes cleanup functionality.
+   */
+  public function testSlashes() {
+    $langcode = LANGUAGE_NONE;
+
+    // Create a File field with 'node/[node:title]' as the File path and
+    // '[node:title].[file:ffp-extension-original]' as the File name.
+    $field_name                                                 = drupal_strtolower($this->randomName());
+    $instance_settings['filefield_paths']['file_path']['value'] = 'node/[node:title]';
+    $instance_settings['filefield_paths']['file_name']['value'] = '[node:title].[file:ffp-extension-original]';
+    $this->createFileField($field_name, $this->content_type, array(), $instance_settings);
+
+    // Create a node with a test file.
+    $test_file = $this->getTestFile('text');
+
+    $title                                      = "{$this->randomName()}/{$this->randomName()}";
+    $edit['title']                              = $title;
+    $edit["body[{$langcode}][0][value]"]        = '';
+    $edit["files[{$field_name}_{$langcode}_0]"] = drupal_realpath($test_file->uri);
+    $this->drupalPost("node/add/{$this->content_type}", $edit, t('Save'));
+
+    // Get created Node ID.
+    $matches = array();
+    preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches);
+    $nid = $matches[1];
+
+    // Ensure slashes are present in file path and name.
+    $node = node_load($nid);
+    $this->assertEqual("public://node/{$title}/{$title}.txt", $node->{$field_name}[$langcode][0]['uri']);
+
+    // Remove slashes.
+    $edit = array(
+      'instance[settings][filefield_paths][file_path][options][slashes]' => TRUE,
+      'instance[settings][filefield_paths][file_name][options][slashes]' => TRUE,
+      'instance[settings][filefield_paths][retroactive_update]'          => TRUE,
+    );
+    $this->drupalPost("admin/structure/types/manage/{$this->content_type}/fields/{$field_name}", $edit, t('Save settings'));
+
+    // Ensure slashes are not present in file path and name.
+    $node  = node_load($nid, NULL, TRUE);
+    $title = str_replace('/', '', $title);
+    $this->assertEqual("public://node/{$title}/{$title}.txt", $node->{$field_name}[$langcode][0]['uri']);
+  }
+
+  /**
+   * Test a file usage of a basic file upload with File (Field) Paths.
+   */
+  public function testFileUsage() {
+    // Create a File field with 'node/[node:nid]' as the File path.
+    $field_name                                                 = drupal_strtolower($this->randomName());
+    $instance_settings['filefield_paths']['file_path']['value'] = 'node/[node:nid]';
+    $this->createFileField($field_name, $this->content_type, array(), $instance_settings);
+
+    // Create a node with a test file.
+    $test_file = $this->getTestFile('text');
+    $nid       = $this->uploadNodeFile($test_file, $field_name, $this->content_type);
+
+    // Get file usage for uploaded file.
+    $node  = node_load($nid, NULL, TRUE);
+    $items = field_get_items('node', $node, $field_name);
+    $file  = file_load($items[0]['fid']);
+    $usage = file_usage_list($file);
+
+    // Ensure file usage count for new node is correct.
+    $this->assert(isset($usage['file']['node'][$nid]) && $usage['file']['node'][$nid] == 1, t('File usage count for new node is correct.'));
+
+    // Update node.
+    $this->drupalPost("node/{$nid}/edit", array(), t('Save'));
+    $usage = file_usage_list($file);
+
+    // Ensure file usage count for updated node is correct.
+    $this->assert(isset($usage['file']['node'][$nid]) && $usage['file']['node'][$nid] == 1, t('File usage count for updated node is correct.'));
+
+    // Update node with revision.
+    $this->drupalPost("node/{$nid}/edit", array('revision' => TRUE), t('Save'));
+    $usage = file_usage_list($file);
+
+    // Ensure file usage count for updated node with revision is correct.
+    $this->assert(isset($usage['file']['node'][$nid]) && $usage['file']['node'][$nid] == 2, t('File usage count for updated node with revision is correct.'));
+  }
+
+  /**
+   * Test File (Field) Paths works with read-only stream wrappers.
+   */
+  public function testReadOnly() {
+    // Create a File field.
+    $field_name        = drupal_strtolower($this->randomName());
+    $field_settings    = array('uri_scheme' => 'ffp');
+    $instance_settings = array('file_directory' => "fields/{$field_name}");
+    $this->createFileField($field_name, $this->content_type, $field_settings, $instance_settings);
+
+    // Get a test file.
+    $file = $this->getTestFile('image');
+
+    // Prepare the file for the test 'ffp://' read-only stream wrapper.
+    $file->uri = str_replace('public', 'ffp', $file->uri);
+    $uri       = file_stream_wrapper_uri_normalize($file->uri);
+
+    // Create a file object.
+    $file           = new stdClass();
+    $file->fid      = NULL;
+    $file->uri      = $uri;
+    $file->filename = basename($file->uri);
+    $file->filemime = file_get_mimetype($file->uri);
+    $file->uid      = $GLOBALS['user']->uid;
+    $file->status   = FILE_STATUS_PERMANENT;
+    $file->display  = TRUE;
+    file_save($file);
+
+    // Attach the file to a node.
+    $node                                = array();
+    $node['type']                        = $this->content_type;
+    $node[$field_name][LANGUAGE_NONE][0] = (array) $file;
+
+    $node = $this->drupalCreateNode($node);
+
+    // Ensure file has been attached to a node.
+    $this->assert(isset($node->{$field_name}[LANGUAGE_NONE][0]) && !empty($node->{$field_name}[LANGUAGE_NONE][0]), t('Read-only file is correctly attached to a node.'));
+
+    $edit                                                            = array();
+    $edit['instance[settings][filefield_paths][retroactive_update]'] = TRUE;
+    $edit['instance[settings][filefield_paths][file_path][value]']   = 'node/[node:nid]';
+    $this->drupalPost("admin/structure/types/manage/{$this->content_type}/fields/{$field_name}", $edit, t('Save settings'));
+
+    // Ensure file is still in original location.
+    $this->drupalGet("node/{$node->nid}");
+    $this->assertRaw("{$this->public_files_directory}/{$file->filename}", t('Read-only file not affected by Retroactive updates.'));
+  }
+}

+ 90 - 0
sites/all/modules/filefield_paths/tests/filefield_paths.test

@@ -0,0 +1,90 @@
+<?php
+
+/**
+ * @file
+ * Tests for the File (Field) Paths module.
+ */
+
+/**
+ * Class FileFieldPathsTestCase
+ */
+class FileFieldPathsTestCase extends FileFieldTestCase {
+  var $content_type = NULL;
+  var $public_files_directory = NULL;
+
+  /**
+   * @inheritdoc
+   */
+  function setUp() {
+    // Setup required modules.
+    $modules = func_get_args();
+    if (isset($modules[0]) && is_array($modules[0])) {
+      $modules = $modules[0];
+    }
+    $modules[] = 'filefield_paths_test';
+    $modules[] = 'image';
+    $modules[] = 'token';
+    parent::setUp($modules);
+
+    // Include all optional dependency files.
+    $dirname  = dirname(__FILE__) . "/../modules";
+    $includes = file_scan_directory($dirname, '/.inc$/');
+    foreach (array_keys($includes) as $file) {
+      require_once $file;
+    }
+
+    // Create a content type.
+    $content_type       = $this->drupalCreateContentType();
+    $this->content_type = $content_type->name;
+  }
+
+  /**
+   * @inheritdoc
+   */
+  function createFileField($name, $type_name, $field_settings = array(), $instance_settings = array(), $widget_settings = array()) {
+    parent::createFileField($name, $type_name, $field_settings, $instance_settings, $widget_settings);
+    $this->drupalPost("admin/structure/types/manage/{$this->content_type}/fields/{$name}", array(), t('Save settings'));
+  }
+
+  /**
+   * Creates a new image field.
+   *
+   * @param $name
+   *   The name of the new field (all lowercase), exclude the "field_" prefix.
+   * @param $type_name
+   *   The node type that this field will be added to.
+   * @param $field_settings
+   *   A list of field settings that will be added to the defaults.
+   * @param $instance_settings
+   *   A list of instance settings that will be added to the instance defaults.
+   * @param $widget_settings
+   *   A list of widget settings that will be added to the widget defaults.
+   */
+  function createImageField($name, $type_name, $field_settings = array(), $instance_settings = array(), $widget_settings = array()) {
+    $field             = array(
+      'field_name'  => $name,
+      'type'        => 'image',
+      'settings'    => array(),
+      'cardinality' => !empty($field_settings['cardinality']) ? $field_settings['cardinality'] : 1,
+    );
+    $field['settings'] = array_merge($field['settings'], $field_settings);
+    field_create_field($field);
+
+    $instance                       = array(
+      'field_name'  => $name,
+      'label'       => $name,
+      'entity_type' => 'node',
+      'bundle'      => $type_name,
+      'required'    => !empty($instance_settings['required']),
+      'settings'    => array(),
+      'widget'      => array(
+        'type'     => 'image_image',
+        'settings' => array(),
+      ),
+    );
+    $instance['settings']           = array_merge($instance['settings'], $instance_settings);
+    $instance['widget']['settings'] = array_merge($instance['widget']['settings'], $widget_settings);
+    field_create_instance($instance);
+    $this->drupalPost("admin/structure/types/manage/{$this->content_type}/fields/{$name}", array(), t('Save settings'));
+  }
+}

+ 104 - 0
sites/all/modules/filefield_paths/tests/filefield_paths.text_replace.test

@@ -0,0 +1,104 @@
+<?php
+
+/**
+ * @file
+ * Tests for the File (Field) Paths module.
+ */
+
+/**
+ * Class FileFieldPathsTextReplaceTestCase
+ */
+class FileFieldPathsTextReplaceTestCase extends FileFieldPathsTestCase {
+  /**
+   * @inheritdoc
+   */
+  public static function getInfo() {
+    return array(
+      'name'        => 'Text replace functionality',
+      'description' => 'Tests text replace functionality.',
+      'group'       => 'File (Field) Paths',
+    );
+  }
+
+  /**
+   * Generates all variations of the URI for text replacement.
+   *
+   * @param        $uri
+   * @param string $type
+   *
+   * @return mixed
+   */
+  protected function getPathVariations($uri, $type = 'image') {
+    // Force clean urls on.
+    $GLOBALS['conf']['clean_url'] = TRUE;
+
+    $variations['uri']      = $uri;
+    $variations['absolute'] = urldecode(file_create_url($uri));
+    $variations['relative'] = parse_url($variations['absolute'], PHP_URL_PATH);
+
+    if ($type == 'image') {
+      $variations['image_style']          = urldecode(image_style_url('thumbnail', $uri));
+      $variations['image_style_relative'] = parse_url($variations['image_style'], PHP_URL_PATH) . '?' . parse_url($variations['image_style'], PHP_URL_QUERY);
+    }
+
+    foreach ($variations as $key => $value) {
+      $variations["{$key}_urlencode"]          = urlencode($value);
+      $variations["{$key}_drupal_encode_path"] = drupal_encode_path($value);
+    }
+
+    return $variations;
+  }
+
+  /**
+   * Test text replace with multiple file uploads.
+   */
+  public function testTextReplace() {
+    $langcode = LANGUAGE_NONE;
+
+    // Create a File field with 'node/[node:nid]' as the File path and
+    // '[node:nid].png’ as the File name,
+    $field_name                                                 = drupal_strtolower($this->randomName());
+    $instance_settings['filefield_paths']['file_path']['value'] = 'node/[node:nid]';
+    $instance_settings['filefield_paths']['file_name']['value'] = '[node:nid].png';
+    $this->createImageField($field_name, $this->content_type, array(), $instance_settings);
+
+    // Prepare test files.
+    $test_files['basic_image']   = $this->getTestFile('image');
+    $test_files['complex_image'] = $this->getTestFile('image');
+    file_unmanaged_copy($test_files['complex_image']->uri, 'public://test image.png');
+    $files                       = file_scan_directory('public://', '/test image\.png/');
+    $test_files['complex_image'] = current($files);
+
+    // Iterate over each test file.
+    foreach ($test_files as $type => $test_file) {
+      // Get the available file paths for the test file.
+      $uri          = str_replace('public://', variable_get('filefield_paths_temp_location', 'public://filefield_paths') . '/', $test_file->uri);
+      $source_paths = $this->getPathVariations($uri);
+
+      // Upload a file and reference the original path(s) to the file in the body
+      // field.
+      $edit['title']                              = $this->randomName();
+      $edit["body[{$langcode}][0][value]"]        = '';
+      $edit["files[{$field_name}_{$langcode}_0]"] = drupal_realpath($test_file->uri);
+      foreach ($source_paths as $key => $value) {
+        $edit["body[{$langcode}][0][value]"] .= "{$key}: {$value}\n";
+      }
+      $this->drupalPost("node/add/{$this->content_type}", $edit, t('Save'));
+
+      // Get created Node ID.
+      $matches = array();
+      preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches);
+      $nid = $matches[1];
+
+      // Ensure body field has updated file path.
+      $node              = node_load($nid);
+      $destination_paths = $this->getPathVariations($node->{$field_name}[$langcode][0]['uri']);
+      foreach ($destination_paths as $key => $value) {
+        $this->assert($source_paths[$key] !== $destination_paths[$key] && strpos($node->body[$langcode][0]['value'], "{$key}: {$value}") !== FALSE, t('@type %key file path replaced successfully.', array(
+          '@type' => str_replace('_', ' ', drupal_ucfirst($type)),
+          '%key'  => $key
+        )));
+      }
+    }
+  }
+}

+ 103 - 0
sites/all/modules/filefield_paths/tests/filefield_paths.tokens.test

@@ -0,0 +1,103 @@
+<?php
+
+/**
+ * @file
+ * Tests for the File (Field) Paths module.
+ */
+
+/**
+ * Class FileFieldPathsTokensTestCase
+ */
+class FileFieldPathsTokensTestCase extends FileFieldPathsTestCase {
+  /**
+   * @inheritdoc
+   */
+  public static function getInfo() {
+    return array(
+      'name'        => 'Token functionality',
+      'description' => 'Tests File (Field) Paths tokens.',
+      'group'       => 'File (Field) Paths',
+    );
+  }
+
+  /**
+   * @param $token
+   * @param $value
+   * @param $data
+   */
+  public function assertToken($token, $value, $data) {
+    $result = token_replace($token, $data);
+    $this->assertEqual($result, $value, t('Token @token equals @value', array(
+      '@token' => $token,
+      '@value' => $value
+    )));
+  }
+
+  /**
+   * Test token values with a text file.
+   */
+  public function testTokensBasic() {
+    // Prepare a test text file.
+    $text_file = $this->getTestFile('text');
+    file_save($text_file);
+
+    // Ensure tokens are processed correctly.
+    $data = array('file' => $text_file);
+    $this->assertToken('[file:ffp-name-only]', 'text-0', $data);
+    $this->assertToken('[file:ffp-name-only-original]', 'text-0', $data);
+    $this->assertToken('[file:ffp-extension-original]', 'txt', $data);
+  }
+
+  /**
+   * Test token values with a moved text file.
+   */
+  public function testTokensMoved() {
+    // Prepare a test text file.
+    $text_file = $this->getTestFile('text');
+    file_save($text_file);
+
+    // Move the text file.
+    $moved_file = file_move($text_file, 'public://moved.diff');
+
+    // Ensure tokens are processed correctly.
+    $data = array('file' => $moved_file);
+    $this->assertToken('[file:ffp-name-only]', 'moved', $data);
+    $this->assertToken('[file:ffp-name-only-original]', 'text-0', $data);
+    $this->assertToken('[file:ffp-extension-original]', 'txt', $data);
+  }
+
+  /**
+   * Test token values with a multi-extension text file.
+   */
+  public function testTokensMultiExtension() {
+    // Prepare a test text file.
+    $text_file = $this->getTestFile('text');
+    file_unmanaged_copy($text_file->uri, 'public://text.multiext.txt');
+    $files         = file_scan_directory('public://', '/text\.multiext\.txt/');
+    $multiext_file = current($files);
+    file_save($multiext_file);
+
+    // Ensure tokens are processed correctly.
+    $data = array('file' => $multiext_file);
+    $this->assertToken('[file:ffp-name-only]', 'text.multiext', $data);
+    $this->assertToken('[file:ffp-name-only-original]', 'text.multiext', $data);
+    $this->assertToken('[file:ffp-extension-original]', 'txt', $data);
+  }
+
+  /**
+   * Test token value with a UTF file.
+   * @see https://www.drupal.org/node/1292436
+   */
+  public function testTokensUTF() {
+    // Prepare a test text file.
+    $text_file = $this->getTestFile('text');
+    file_unmanaged_copy($text_file->uri, 'public://тест.txt');
+    $files    = file_scan_directory('public://', '/тест\.txt/');
+    $utf_file = current($files);
+    file_save($utf_file);
+
+    // Ensure tokens are processed correctly.
+    $data = array('file' => $utf_file);
+    $this->assertToken('[file:ffp-name-only]', 'тест', $data);
+  }
+}

+ 81 - 0
sites/all/modules/filefield_paths/tests/filefield_paths.update.test

@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * @file
+ * Tests for the File (Field) Paths module.
+ */
+
+/**
+ * Class FileFieldPathsUpdatesCase
+ */
+class FileFieldPathsUpdatesCase extends FileFieldPathsTestCase {
+  /**
+   * @inheritdoc
+   */
+  public static function getInfo() {
+    return array(
+      'name'        => 'Update functionality',
+      'description' => 'Tests retroactive and active updates functionality.',
+      'group'       => 'File (Field) Paths',
+    );
+  }
+
+  /**
+   * Test behaviour of Retroactive updates when no updates are needed.
+   */
+  public function testRetroEmpty() {
+    // Create a File field.
+    $field_name = drupal_strtolower($this->randomName());
+    $this->createFileField($field_name, $this->content_type);
+
+    // Trigger retroactive updates.
+    $edit = array(
+      'instance[settings][filefield_paths][retroactive_update]' => TRUE
+    );
+    $this->drupalPost("admin/structure/types/manage/{$this->content_type}/fields/{$field_name}", $edit, t('Save settings'));
+
+    // Ensure no errors are thrown.
+    $this->assertNoText('Error', t('No errors were found.'));
+  }
+
+  /**
+   * Test basic Retroactive updates functionality.
+   */
+  public function testRetroBasic() {
+    // Create an Image field.
+    $field_name = drupal_strtolower($this->randomName());
+    $this->createImageField($field_name, $this->content_type, array());
+
+    // Modify instance settings.
+    $instance = field_info_instance('node', $field_name, $this->content_type);
+
+    $instance['display']['default']['settings']['image_style'] = 'thumbnail';
+    $instance['display']['default']['settings']['image_link']  = 'content';
+    field_update_instance($instance);
+    $this->drupalGet("admin/structure/types/manage/{$this->content_type}/display");
+    $original_instance = field_info_instance('node', $field_name, $this->content_type);
+
+    // Create a node with a test file.
+    $test_file = $this->getTestFile('image');
+    $nid       = $this->uploadNodeFile($test_file, $field_name, $this->content_type);
+
+    // Ensure that the file is in the default path.
+    $this->drupalGet("node/{$nid}");
+    $this->assertRaw("{$this->public_files_directory}/styles/thumbnail/public/{$test_file->name}", t('The File is in the default path.'));
+
+    // Trigger retroactive updates.
+    $edit['instance[settings][filefield_paths][retroactive_update]'] = TRUE;
+    $edit['instance[settings][filefield_paths][file_path][value]']   = 'node/[node:nid]';
+    $this->drupalPost("admin/structure/types/manage/{$this->content_type}/fields/{$field_name}", $edit, t('Save settings'));
+
+    // Ensure instance display settings haven't changed.
+    // @see https://www.drupal.org/node/2276435
+    drupal_static_reset('_field_info_field_cache');
+    $instance = field_info_instance('node', $field_name, $this->content_type);
+    $this->assert($original_instance['display'] === $instance['display'], t('Instance settings have not changed.'));
+
+    // Ensure that the file path has been retroactively updated.
+    $this->drupalGet("node/{$nid}");
+    $this->assertRaw("{$this->public_files_directory}/styles/thumbnail/public/node/{$nid}/{$test_file->name}", t('The File path has been retroactively updated.'));
+  }
+}

+ 12 - 0
sites/all/modules/filefield_paths/tests/filefield_paths_test.info

@@ -0,0 +1,12 @@
+name = File (Field) Paths tests
+description = Support module for File (Field) Paths related testing.
+package = Testing
+dependencies[] = filefield_paths
+core = 7.x
+hidden = TRUE
+
+; Information added by Drupal.org packaging script on 2018-08-14
+version = "7.x-1.1"
+core = "7.x"
+project = "filefield_paths"
+datestamp = "1534256584"

+ 16 - 0
sites/all/modules/filefield_paths/tests/filefield_paths_test.module

@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * @file
+ * Core functions for the File (Field) Paths tests module.
+ */
+
+/**
+ * Implements hook_stream_wrappers_alter().
+ *
+ * @param $wrappers
+ */
+function filefield_paths_test_stream_wrappers_alter(&$wrappers) {
+  $wrappers['ffp']         = $wrappers['public'];
+  $wrappers['ffp']['type'] = STREAM_WRAPPERS_READ_VISIBLE;
+}

+ 84 - 0
sites/all/modules/filefield_paths/tests/pathauto.test

@@ -0,0 +1,84 @@
+<?php
+
+/**
+ * @file
+ * Pathauto module tests for the File (Field) Paths module.
+ */
+
+/**
+ * Class FileFieldPathsPathautoCase
+ */
+class FileFieldPathsPathautoCase extends FileFieldPathsTestCase {
+  /**
+   * @inheritdoc
+   */
+  function setUp() {
+    // Setup required modules.
+    parent::setUp(array('pathauto'));
+  }
+
+  /**
+   * @inheritdoc
+   */
+  public static function getInfo() {
+    return array(
+      'name'        => 'Pathauto integration',
+      'description' => 'Tests the Pathauto module integration.',
+      'group'       => 'File (Field) Paths',
+    );
+  }
+
+  /**
+   * Test File (Field) Paths Pathauto UI.
+   */
+  public function testUI() {
+    // Create a File field.
+    $field_name = drupal_strtolower($this->randomName());
+    $this->createFileField($field_name, $this->content_type);
+
+    // Ensure File (Field) Paths Pathauto settings are present and available.
+    $this->drupalGet("admin/structure/types/manage/{$this->content_type}/fields/{$field_name}");
+    foreach (array('path', 'name') as $field) {
+      $this->assertField("instance[settings][filefield_paths][file_{$field}][options][pathauto]", t('Pathauto checkbox is present in File @field settings.', array('@field' => drupal_ucfirst($field))));
+
+      $element = $this->xpath('//input[@name=:name]/@disabled', array(':name' => "instance[settings][filefield_paths][file_{$field}][options][pathauto]"));
+      $this->assert(empty($element), t('Pathauto checkbox is not disabled in File @field settings.', array('@field' => drupal_ucfirst($field))));
+    }
+  }
+
+  /**
+   * Test Pathauto cleanup in File (Field) Paths.
+   */
+  public function testPathauto() {
+    $langcode = LANGUAGE_NONE;
+
+    // Create a File field.
+    $field_name = drupal_strtolower($this->randomName());
+
+    $instance_settings['filefield_paths']['file_path']['value']               = 'node/[node:title]';
+    $instance_settings['filefield_paths']['file_path']['options']['pathauto'] = TRUE;
+    $instance_settings['filefield_paths']['file_name']['value']               = '[node:title].[file:ffp-extension-original]';
+    $instance_settings['filefield_paths']['file_name']['options']['pathauto'] = TRUE;
+
+    $this->createFileField($field_name, $this->content_type, array(), $instance_settings);
+
+    // Create a node with a test file.
+    $test_file     = $this->getTestFile('text');
+    $edit['title'] = $this->randomString() . ' ' . $this->randomString();
+
+    $edit['files[' . $field_name . '_' . $langcode . '_0]'] = drupal_realpath($test_file->uri);
+    $this->drupalPost("node/add/{$this->content_type}", $edit, t('Save'));
+
+    // Ensure that file path/name have been processed correctly by Pathauto.
+    $node = node_load(1);
+
+    module_load_include('inc', 'pathauto');
+    $parts = explode('/', $node->title);
+    foreach ($parts as &$part) {
+      $part = pathauto_cleanstring($part);
+    }
+    $title = implode('/', $parts);
+
+    $this->assertEqual($node->{$field_name}[$langcode][0]['uri'], "public://node/{$title}/{$title}.txt", t('File path/name has been processed correctly by Pathauto'));
+  }
+}

+ 90 - 0
sites/all/modules/filefield_paths/tests/redirect.test

@@ -0,0 +1,90 @@
+<?php
+
+/**
+ * @file
+ * Redirect module tests for the File (Field) Paths module.
+ */
+
+/**
+ * Class FileFieldPathsRedirectTestCase
+ */
+class FileFieldPathsRedirectTestCase extends FileFieldPathsTestCase {
+  /**
+   * @inheritdoc
+   */
+  function setUp() {
+    // Setup required modules.
+    parent::setUp(array('redirect'));
+  }
+
+  /**
+   * @inheritdoc
+   */
+  public static function getInfo() {
+    return array(
+      'name'        => 'Redirect module integration',
+      'description' => 'Test redirect module integration.',
+      'group'       => 'File (Field) Paths',
+    );
+  }
+
+  /**
+   * Test File (Field) Paths Redirect UI.
+   */
+  public function testUI() {
+    // Create a File field.
+    $field_name = drupal_strtolower($this->randomName());
+    $this->createFileField($field_name, $this->content_type);
+
+    // Ensure File (Field) Paths Pathauto settings are present and available.
+    $this->drupalGet("admin/structure/types/manage/{$this->content_type}/fields/{$field_name}");
+
+    $this->assertField('instance[settings][filefield_paths][redirect]', t('Redirect checkbox is present in File (Field) Path settings.'));
+
+    $element = $this->xpath('//input[@name=:name]/@disabled', array(':name' => 'instance[settings][filefield_paths][redirect]'));
+    $this->assert(empty($element), t('Redirect checkbox is not disabled.'));
+  }
+
+  /**
+   * Test File (Field) Paths Redirect functionality.
+   */
+  public function testRedirect() {
+    global $base_path;
+    $langcode = LANGUAGE_NONE;
+
+    // Create a File field with a random File path.
+    $field_name                                                 = drupal_strtolower($this->randomName());
+    $instance_settings['filefield_paths']['file_path']['value'] = $this->randomName();
+    $this->createFileField($field_name, $this->content_type, array(), $instance_settings);
+
+    // Create a node with a test file.
+    $test_file = $this->getTestFile('text');
+    $nid       = $this->uploadNodeFile($test_file, $field_name, $this->content_type);
+
+    // Get processed source file uri.
+    $node   = node_load($nid, NULL, TRUE);
+    $source = $node->{$field_name}[$langcode][0]['uri'];
+
+    // Update file path and create redirect.
+    $edit = array(
+      'instance[settings][filefield_paths][file_path][value]'   => $this->randomName(),
+      'instance[settings][filefield_paths][redirect]'           => TRUE,
+      'instance[settings][filefield_paths][retroactive_update]' => TRUE,
+    );
+    $this->drupalPost("admin/structure/types/manage/{$this->content_type}/fields/{$field_name}", $edit, t('Save settings'));
+
+    // Get processed destination file uri.
+    $node        = node_load($nid, NULL, TRUE);
+    $destination = $node->{$field_name}[$langcode][0]['uri'];
+
+    // Ensure that the source uri redirects to the destination uri.
+    $parsed_source   = parse_url(file_create_url($source), PHP_URL_PATH);
+    $redirect_source = drupal_substr(urldecode($parsed_source), drupal_strlen($base_path));
+
+    $parsed_destination   = parse_url(file_create_url($destination), PHP_URL_PATH);
+    $redirect_destination = drupal_substr(urldecode($parsed_destination), drupal_strlen($base_path));
+
+    $redirect = redirect_load_by_source($redirect_source);
+    $this->assert(is_object($redirect) && $redirect->redirect == $redirect_destination, t('Redirect created for relocated file.'));
+  }
+}

+ 82 - 0
sites/all/modules/filefield_paths/tests/transliteration.test

@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * @file
+ * Transliteration module tests for the File (Field) Paths module.
+ */
+
+/**
+ * Class FileFieldPathsTransliterationCase
+ */
+class FileFieldPathsTransliterationCase extends FileFieldPathsTestCase {
+  /**
+   * @inheritdoc
+   */
+  function setUp() {
+    // Setup required modules.
+    parent::setUp(array('transliteration'));
+  }
+
+  /**
+   * @inheritdoc
+   */
+  public static function getInfo() {
+    return array(
+      'name'        => 'Transliteration integration',
+      'description' => 'Tests the Transliteration module integration.',
+      'group'       => 'File (Field) Paths',
+    );
+  }
+
+  /**
+   * Test File (Field) Paths Transliteration UI.
+   */
+  public function testUI() {
+    // Create a File field.
+    $field_name = drupal_strtolower($this->randomName());
+    $this->createFileField($field_name, $this->content_type);
+
+    // Ensure File (Field) Paths Transliteration settings are present and available.
+    $this->drupalGet("admin/structure/types/manage/{$this->content_type}/fields/{$field_name}");
+    foreach (array('path', 'name') as $field) {
+      $this->assertField("instance[settings][filefield_paths][file_{$field}][options][transliterate]", t('Transliteration checkbox is present in File @field settings.', array('@field' => drupal_ucfirst($field))));
+
+      $element = $this->xpath('//input[@name=:name]/@disabled', array(':name' => "instance[settings][filefield_paths][file_{$field}][options][transliterate]"));
+      $this->assert(empty($element), t('Transliteration checkbox is not disabled in File @field settings.', array('@field' => drupal_ucfirst($field))));
+    }
+  }
+
+  /**
+   * Test Transliteration cleanup in File (Field) Paths.
+   */
+  public function testTransliteration() {
+    $langcode = LANGUAGE_NONE;
+
+    // Create a File field.
+    $field_name = drupal_strtolower($this->randomName());
+
+    $instance_settings['filefield_paths']['file_path']['value']                    = 'node/[node:title]';
+    $instance_settings['filefield_paths']['file_path']['options']['transliterate'] = TRUE;
+    $instance_settings['filefield_paths']['file_name']['value']                    = '[node:title].[file:ffp-extension-original]';
+    $instance_settings['filefield_paths']['file_name']['options']['transliterate'] = TRUE;
+
+    $this->createFileField($field_name, $this->content_type, array(), $instance_settings);
+
+    // Create a node with a test file.
+    $test_file     = $this->getTestFile('text');
+    $edit['title'] = 'тест';
+
+    $edit['files[' . $field_name . '_' . $langcode . '_0]'] = drupal_realpath($test_file->uri);
+    $this->drupalPost("node/add/{$this->content_type}", $edit, t('Save'));
+
+    // Get created Node ID.
+    $matches = array();
+    preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches);
+    $nid = $matches[1];
+
+    // Ensure that file path/name have been processed correctly by
+    // Transliteration.
+    $node = node_load($nid);
+    $this->assertEqual($node->{$field_name}[$langcode][0]['uri'], "public://node/test/test.txt", t('File path/name has been processed correctly by Transliteration'));
+  }
+}

+ 74 - 0
sites/all/modules/uuid/.travis.yml

@@ -0,0 +1,74 @@
+language: php
+sudo: false
+
+php:
+  - 5.5
+  - 5.6
+  - 7.0
+  - hhvm
+
+matrix:
+  fast_finish: true
+  allow_failures:
+    - php: hhvm
+
+mysql:
+  database: drupal
+  username: root
+  encoding: utf8
+
+install:
+  # add composer's global bin directory to the path
+  # see: https://github.com/drush-ops/drush#install---composer
+  - export PATH="$HOME/.composer/vendor/bin:$PATH"
+
+  # install drush globally
+  - composer global require drush/drush:7.*
+
+  # Install PHP_CodeSniffer and Drupal config
+  - composer global require drupal/coder
+  - phpcs --config-set installed_paths ~/.composer/vendor/drupal/coder/coder_sniffer
+
+  # Create the database
+  - mysql -e 'create database drupal;'
+
+before_script:
+
+  # Disable sendmail
+  - echo sendmail_path=`which true` >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
+
+  # Increase the MySQL connection timeout on the PHP end.
+  - echo "mysql.connect_timeout=3000" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
+  - echo "default_socket_timeout=3000" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
+
+  # Increase the MySQL server timetout and packet size.
+  - mysql -e "SET GLOBAL wait_timeout = 36000;"
+  - mysql -e "SET GLOBAL max_allowed_packet = 33554432;"
+
+  # Download Drupal 7.x
+  - drush pm-download drupal-7 --destination=/tmp --drupal-project-rename=drupal
+
+  # Add our module
+  - ln -s $(pwd) /tmp/drupal/sites/all/modules/
+
+  # Switch to the drupal site directory
+  - cd /tmp/drupal
+
+  # Install site and dependencies
+  - drush -vv --yes site-install --db-url=mysql://root:@127.0.0.1/drupal
+  - drush pm-download entity
+  - drush pm-enable simpletest entity uuid --yes
+
+  # Use the PHP builtin webserver to serve the site.
+  #- drush runserver 8080 > /dev/null 2>&1 &
+  - drush runserver 127.0.0.1:8888 > ~/server.log 2>&1 &
+  - export counter=0; until nc -zv localhost 8888; do if [ $counter -ge 12 ]; then echo "Failed to start server."; exit 1; fi; echo "Waiting for web server to start on port 8888..."; sleep 5; counter=$[$counter +1]; done
+
+script:
+  - cd /tmp/drupal
+  - php ./scripts/run-tests.sh --verbose --color --php "$(which php)" --url http://127.0.0.1:8888 UUID | tee ~/tests.log
+  - phpcs --standard=Drupal --extensions=php,module,inc,install,test,profile,theme sites/all/modules/uuid
+
+after_failure:
+  # See what happened with the server.
+  - cat ~/server.log

+ 1 - 0
sites/all/modules/uuid/README.txt

@@ -11,6 +11,7 @@ FEATURES
  * Automatic UUID generation:
  * Automatic UUID generation:
    UUIDs will be generated for all core entities. An API is provided for other
    UUIDs will be generated for all core entities. An API is provided for other
    modules to enable support for custom entities.
    modules to enable support for custom entities.
+   See https://www.drupal.org/node/2387671
  * UUID API for entities, properties and fields:
  * UUID API for entities, properties and fields:
    With this unified API you can load entities with entity_uuid_load() so that
    With this unified API you can load entities with entity_uuid_load() so that
    all supported properties and fields are made with UUID references. You can
    all supported properties and fields are made with UUID references. You can

+ 17 - 2
sites/all/modules/uuid/plugins/arguments/entity_uuid.inc

@@ -6,8 +6,7 @@
  */
  */
 
 
 /**
 /**
- * Plugins are described by creating a $plugin array which will be used
- * by the system that includes this file.
+ * CTools UUID entity context plugin definition.
  */
  */
 $plugin = array(
 $plugin = array(
   'title' => t("Entity: UUID"),
   'title' => t("Entity: UUID"),
@@ -17,11 +16,27 @@ $plugin = array(
   'get children' => 'uuid_entity_uuid_get_children',
   'get children' => 'uuid_entity_uuid_get_children',
 );
 );
 
 
+/**
+ * Fetches the "child" information for a given parent entity.
+ *
+ * @todo document me properly.
+ *
+ * @return array
+ *   The children.
+ */
 function uuid_entity_uuid_get_child($plugin, $parent, $child) {
 function uuid_entity_uuid_get_child($plugin, $parent, $child) {
   $plugins = uuid_entity_uuid_get_children($plugin, $parent);
   $plugins = uuid_entity_uuid_get_children($plugin, $parent);
   return $plugins[$parent . ':' . $child];
   return $plugins[$parent . ':' . $child];
 }
 }
 
 
+/**
+ * Fetches all children types for a given parent entity.
+ *
+ * @todo document me properly.
+ *
+ * @return array
+ *   All the children.
+ */
 function uuid_entity_uuid_get_children($original_plugin, $parent) {
 function uuid_entity_uuid_get_children($original_plugin, $parent) {
   $entities = entity_get_info();
   $entities = entity_get_info();
   $plugins = array();
   $plugins = array();

+ 2 - 0
sites/all/modules/uuid/uuid.admin.inc

@@ -42,7 +42,9 @@ function uuid_devel_load_by_uuid($entity_type, $entity) {
     // Get the keys for local ID and UUID.
     // Get the keys for local ID and UUID.
     $uuid_key = $info['entity keys']['uuid'];
     $uuid_key = $info['entity keys']['uuid'];
     $uuid_entities = entity_uuid_load($entity_type, array($entity->{$uuid_key}));
     $uuid_entities = entity_uuid_load($entity_type, array($entity->{$uuid_key}));
+    // @codingStandardsIgnoreStart
     return kdevel_print_object(reset($uuid_entities), '$' . $entity_type . '->');
     return kdevel_print_object(reset($uuid_entities), '$' . $entity_type . '->');
+    // @codingStandardsIgnoreEnd
   }
   }
   else {
   else {
     return t("This entity doesn't support UUID.");
     return t("This entity doesn't support UUID.");

+ 13 - 39
sites/all/modules/uuid/uuid.api.php

@@ -5,26 +5,6 @@
  * Hooks provided by the UUID module.
  * Hooks provided by the UUID module.
  */
  */
 
 
-/**
- * Defines one or more UUID generators exposed by a module.
- *
- * @return
- *   An associative array with the key being the machine name for the
- *   implementation and the values being an array with the following keys:
- *     - title: The human readable name for the generator.
- *     - callback: The function to be called for generating the UUID.
- *
- * @see uuid_get_info()
- */
-function hook_uuid_info() {
-  $generators = array();
-  $generators['my_module'] = array(
-    'title' => t('My module UUID generator'),
-    'callback' => 'my_module_generate_uuid',
-  );
-  return $generators;
-}
-
 /**
 /**
  * Ensures all records have a UUID assigned to them.
  * Ensures all records have a UUID assigned to them.
  *
  *
@@ -38,39 +18,35 @@ function hook_uuid_sync() {
 }
 }
 
 
 /**
 /**
- * Let modules transform their properties with local IDs to UUIDs when an
- * entity is loaded.
+ * Transform entity properties from local IDs to UUIDs when they are loaded.
  */
  */
 function hook_entity_uuid_load(&$entities, $entity_type) {
 function hook_entity_uuid_load(&$entities, $entity_type) {
 
 
 }
 }
 
 
 /**
 /**
- * Let modules transform their fields with local IDs to UUIDs when an entity
- * is loaded.
+ * Transform field values from local IDs to UUIDs when an entity is loaded.
  */
  */
 function hook_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
 function hook_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
 
 
 }
 }
 
 
 /**
 /**
- * Let modules transform their properties with UUIDs to local IDs when an
- * entity is saved.
+ * Transform entity properties from UUIDs to local IDs before entity is saved.
  */
  */
 function hook_entity_uuid_presave(&$entity, $entity_type) {
 function hook_entity_uuid_presave(&$entity, $entity_type) {
 
 
 }
 }
 
 
 /**
 /**
- * Let modules transform their fields with UUIDs to local IDs when an entity
- * is saved.
+ * Transform field values from UUIDs to local IDs before an entity is saved.
  */
  */
 function hook_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
 function hook_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
 
 
 }
 }
 
 
 /**
 /**
- * Let modules transform their properties when an entity is saved.
+ * Transform entity properties after an entity is saved.
  */
  */
 function hook_entity_uuid_save($entity, $entity_type) {
 function hook_entity_uuid_save($entity, $entity_type) {
 
 
@@ -78,20 +54,24 @@ function hook_entity_uuid_save($entity, $entity_type) {
 
 
 /**
 /**
  * Let modules act when an entity is deleted.
  * Let modules act when an entity is deleted.
+ *
+ * Generally hook_entity_delete() should be used instead of this hook.
+ *
+ * @see hook_entity_delete()
  */
  */
 function hook_entity_uuid_delete($entity, $entity_type) {
 function hook_entity_uuid_delete($entity, $entity_type) {
 
 
 }
 }
 
 
 /**
 /**
- * Let modules modify paths when they are being converted to UUID ones.
+ * Modifies paths when they are being converted to UUID ones.
  */
  */
 function hook_uuid_menu_path_to_uri_alter($path, &$uri) {
 function hook_uuid_menu_path_to_uri_alter($path, &$uri) {
 
 
 }
 }
 
 
 /**
 /**
- * Let modules modify paths when they are being converted from UUID ones.
+ * Modifies paths when they are being converted from UUID ones.
  */
  */
 function hook_uuid_menu_uri_to_path(&$path, $uri) {
 function hook_uuid_menu_uri_to_path(&$path, $uri) {
 
 
@@ -121,14 +101,14 @@ function hook_uuid_entities_post_rebuild($plan_name) {
 /**
 /**
  * Let other modules do things before default entities are created on revert.
  * Let other modules do things before default entities are created on revert.
  */
  */
-function hook_uuid_entities_pre_rebuild($plan_name) {
+function hook_uuid_entities_pre_revert($plan_name) {
 
 
 }
 }
 
 
 /**
 /**
  * Let other modules do things after default entities are created on revert.
  * Let other modules do things after default entities are created on revert.
  */
  */
-function hook_uuid_entities_post_rebuild($plan_name) {
+function hook_uuid_entities_post_revert($plan_name) {
 
 
 }
 }
 
 
@@ -152,12 +132,6 @@ function hook_uuid_entities_features_export_field_alter($entity_type, &$entity,
 function hook_uuid_uri_data($data) {
 function hook_uuid_uri_data($data) {
 }
 }
 
 
-/**
- * Alter UUID URI data after processing.
- */
-function hook_uuid_uri_data($data) {
-}
-
 /**
 /**
  * Alter entity URI before creating UUID URI.
  * Alter entity URI before creating UUID URI.
  */
  */

+ 134 - 98
sites/all/modules/uuid/uuid.core.inc

@@ -32,6 +32,31 @@ function node_entity_uuid_presave(&$entity, $entity_type) {
   if ($entity_type == 'node') {
   if ($entity_type == 'node') {
     entity_property_uuid_to_id($entity, 'user', array('uid', 'revision_uid'));
     entity_property_uuid_to_id($entity, 'user', array('uid', 'revision_uid'));
     entity_property_uuid_to_id($entity, 'node', 'tnid');
     entity_property_uuid_to_id($entity, 'node', 'tnid');
+
+    // A node always must have an author.
+    if (empty($entity->uid)) {
+      global $user;
+      $entity->uid = $user->uid;
+    }
+  }
+}
+
+/**
+ * Implements hook_entity_uuid_save().
+ */
+function node_entity_uuid_save(&$entity, $entity_type) {
+  /*
+   * When a node is translated, the source node's tnid is set to it's own nid.
+   * When deploying the node for the first time the tnid can't be translated
+   * to an nid until after the node has been saved. So if the entity's tnid
+   * is still a uuid at this point it needs to be translated to an nid.
+   */
+  if ($entity_type == 'node' && uuid_is_valid($entity->tnid)) {
+    entity_property_uuid_to_id($entity, 'node', 'tnid');
+    db_update('node')
+      ->fields(array('tnid' => $entity->tnid))
+      ->condition('nid', $entity->nid)
+      ->execute();
   }
   }
 }
 }
 
 
@@ -64,17 +89,33 @@ function book_entity_uuid_presave(&$entity, $entity_type) {
  * Implements hook_entity_uuid_presave().
  * Implements hook_entity_uuid_presave().
  */
  */
 function user_entity_uuid_presave(&$entity, $entity_type) {
 function user_entity_uuid_presave(&$entity, $entity_type) {
-  if ($entity_type == 'user') {
-    if (!empty($entity->picture)) {
-      $uuids = entity_get_id_by_uuid('file', array($entity->picture['uuid']));
-      $fid = current($uuids);
-      if (!$entity->is_new) {
-        $entity->picture = file_load($fid);
-      }
-      else {
-        $entity->picture = $fid;
-      }
-    }
+  if ($entity_type != 'user') {
+    return;
+  }
+
+  /*
+   * We need to ensure new user's passwords are encrypted. The Services module
+   * transparently encrypts the password for new users. md5() is used by
+   * users who's accounts were migrated from Drupal 6 and who haven't updated
+   * their password.
+   */
+  if (isset($entity->pass)
+    && (!('$S$D' == substr($entity->pass, 0, 4)) || preg_match('/^[a-f0-9]{32}$/', $entity->pass))) {
+    // Ensure user's password is hashed.
+    $entity->pass = user_hash_password($entity->pass);
+  }
+
+  if (empty($entity->picture)) {
+    return;
+  }
+
+  $uuids = entity_get_id_by_uuid('file', array($entity->picture['uuid']));
+  $fid = current($uuids);
+  if (!$entity->is_new) {
+    $entity->picture = file_load($fid);
+  }
+  else {
+    $entity->picture = $fid;
   }
   }
 }
 }
 
 
@@ -104,6 +145,10 @@ function comment_entity_uuid_presave(&$entity, $entity_type) {
       break;
       break;
 
 
     case 'comment':
     case 'comment':
+      // entity_make_entity_local() may have unset cid, add back if necessary.
+      if (!isset($entity->cid)) {
+        $entity->cid = NULL;
+      }
       entity_property_uuid_to_id($entity, 'user', array('uid', 'u_uid'));
       entity_property_uuid_to_id($entity, 'user', array('uid', 'u_uid'));
       entity_property_uuid_to_id($entity, 'node', 'nid');
       entity_property_uuid_to_id($entity, 'node', 'nid');
       break;
       break;
@@ -124,11 +169,58 @@ function file_entity_uuid_load(&$entities, $entity_type) {
  */
  */
 function file_entity_uuid_presave(&$entity, $entity_type) {
 function file_entity_uuid_presave(&$entity, $entity_type) {
   if ($entity_type == 'file') {
   if ($entity_type == 'file') {
+    // entity_make_entity_local() may have unset fid, add back if necessary.
+    if (!isset($entity->fid)) {
+      $entity->fid = NULL;
+    }
     entity_property_uuid_to_id($entity, 'user', 'uid');
     entity_property_uuid_to_id($entity, 'user', 'uid');
-    if (isset($entity->file_contents)) {
-      $directory = drupal_dirname($entity->uri);
-      file_prepare_directory($directory, FILE_CREATE_DIRECTORY);
-      file_unmanaged_save_data(base64_decode($entity->file_contents), $entity->uri, FILE_EXISTS_REPLACE);
+
+    // Write the new file to the local filesystem.
+    if (isset($entity->file_contents) && !empty($entity->filesize)) {
+      // Don't try to write it if it uses a stream wrapper that isn't writeable
+      // (for example, if it is a remotely-hosted video).
+      $scheme = file_uri_scheme($entity->uri);
+      $wrappers = file_get_stream_wrappers(STREAM_WRAPPERS_WRITE);
+      if (empty($wrappers[$scheme])) {
+        return;
+      }
+
+      // Check for an existing file with the same URI.
+      $existing_files = file_load_multiple(array(), array('uri' => $entity->uri));
+      $existing = (object) array('uri' => NULL, 'uuid' => NULL);
+      if (count($existing_files)) {
+        $existing = reset($existing_files);
+      }
+
+      // If this is a new file and there is an existing file with the same URI,
+      // but a different uuid then rename this file.
+      if ($entity->is_new && $entity->uri == $existing->uri && $entity->uuid != $existing->uuid) {
+        $uri = $entity->uri;
+        $replace = FILE_EXISTS_RENAME;
+      }
+      // If this has an id, meaning UUID has already matched the uuid to an
+      // existing file, but it has a URI that matches a file with a different
+      // uuid, then load the file with the matching uuid and use the URI from
+      // that file. The existing file with the matching uuid is most likely a
+      // file that was previously renamed, e.g. as in the condition above, to
+      // avoid conflict. The uuid matches because they are the same file, but
+      // the URI does not because an incrementing number was added as part of
+      // the renaming.
+      elseif ($entity->uri == $existing->uri && $entity->uuid != $existing->uuid) {
+        $file = file_load($entity->fid);
+        $uri = $file->uri;
+        $replace = FILE_EXISTS_REPLACE;
+      }
+      // Otherwise create a new file or replace the existing file contents.
+      else {
+        $uri = $entity->uri;
+        $replace = FILE_EXISTS_REPLACE;
+      }
+
+      $directory = drupal_dirname($uri);
+      if (!empty($directory) && file_prepare_directory($directory, FILE_CREATE_DIRECTORY)) {
+        $entity->uri = file_unmanaged_save_data(base64_decode($entity->file_contents), $uri, $replace);
+      }
     }
     }
   }
   }
 }
 }
@@ -172,7 +264,7 @@ function taxonomy_entity_uuid_presave(&$entity, $entity_type) {
  * Implements hook_entity_uuid_load().
  * Implements hook_entity_uuid_load().
  */
  */
 function field_entity_uuid_load(&$entities, $entity_type) {
 function field_entity_uuid_load(&$entities, $entity_type) {
-  foreach ($entities as $i => $entity) {
+  foreach ($entities as $entity) {
     list(, , $bundle_name) = entity_extract_ids($entity_type, $entity);
     list(, , $bundle_name) = entity_extract_ids($entity_type, $entity);
     $instances = field_info_instances($entity_type, $bundle_name);
     $instances = field_info_instances($entity_type, $bundle_name);
 
 
@@ -269,34 +361,8 @@ function image_field_uuid_presave($entity_type, $entity, $field, $instance, $lan
 
 
 /**
 /**
  * Implements hook_field_uuid_load().
  * Implements hook_field_uuid_load().
- */
-function node_reference_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  entity_property_id_to_uuid($items, 'node', 'nid');
-}
-
-/**
- * Implements hook_field_uuid_presave().
- */
-function node_reference_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  entity_property_uuid_to_id($items, 'node', 'nid');
-}
-
-/**
- * Implements hook_field_uuid_load().
- */
-function user_reference_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  entity_property_id_to_uuid($items, 'user', 'uid');
-}
-
-/**
- * Implements hook_field_uuid_presave().
- */
-function user_reference_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  entity_property_uuid_to_id($items, 'user', 'uid');
-}
-
-/**
- * Implements hook_field_uuid_load().
+ *
+ * Kept here because it is in D8 core.
  */
  */
 function entityreference_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
 function entityreference_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
   // TODO: This is not really good, but as of now 'entity_property_id_to_uuid()'
   // TODO: This is not really good, but as of now 'entity_property_id_to_uuid()'
@@ -306,6 +372,8 @@ function entityreference_field_uuid_load($entity_type, $entity, $field, $instanc
 
 
 /**
 /**
  * Implements hook_field_uuid_presave().
  * Implements hook_field_uuid_presave().
+ *
+ * Kept here because it is in D8 core.
  */
  */
 function entityreference_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
 function entityreference_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
   // TODO: This is not really good, but as of now 'entity_property_id_to_uuid()'
   // TODO: This is not really good, but as of now 'entity_property_id_to_uuid()'
@@ -313,38 +381,6 @@ function entityreference_field_uuid_presave($entity_type, $entity, $field, $inst
   entity_property_uuid_to_id($items, $field['settings']['target_type'], 'target_id');
   entity_property_uuid_to_id($items, $field['settings']['target_type'], 'target_id');
 }
 }
 
 
-/**
- * Implements hook_entity_uuid_load().
- */
-function field_collection_entity_uuid_load(&$entities, $entity_type) {
-  if ($entity_type == 'field_collection_item') {
-    entity_property_id_to_uuid($entities, 'field_collection_item', 'value');
-  }
-}
-
-/**
- * Implements hook_entity_uuid_presave().
- */
-function field_collection_entity_uuid_presave(&$entity, $entity_type) {
-  if ($entity_type == 'field_collection_item') {
-    entity_property_uuid_to_id($entity, 'field_collection_item', 'value');
-  }
-}
-
-/**
- * Implements hook_field_uuid_load().
- */
-function field_collection_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  entity_property_id_to_uuid($items, 'field_collection_item', 'value');
-}
-
-/**
- * Implements hook_field_uuid_presave().
- */
-function field_collection_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  entity_property_uuid_to_id($items, 'field_collection_item', 'value');
-}
-
 /**
 /**
  * @} End of "Field implementations"
  * @} End of "Field implementations"
  */
  */
@@ -358,24 +394,35 @@ function field_collection_field_uuid_presave($entity_type, $entity, $field, $ins
  * Implements hook_uuid_entities_features_export_entity_alter().
  * Implements hook_uuid_entities_features_export_entity_alter().
  */
  */
 function node_uuid_entities_features_export_entity_alter(&$entity, $entity_type) {
 function node_uuid_entities_features_export_entity_alter(&$entity, $entity_type) {
-  if ($entity_type == 'node') {
-    foreach (array('data', 'name', 'picture', 'revision_uid', 'last_comment_timestamp') as $property) {
-      if (property_exists($entity, $property)) {
-        unset($entity->{$property});
-      }
+  if ('node' != $entity_type) {
+    return;
+  }
+
+  $properties = array(
+    'data',
+    'name',
+    'picture',
+    'revision_uid',
+    'last_comment_timestamp',
+  );
+  foreach ($properties as $property) {
+    if (property_exists($entity, $property)) {
+      unset($entity->{$property});
     }
     }
   }
   }
 }
 }
 
 
 /**
 /**
- * Implementation of hook_uuid_entities_features_export_entity_alter().
+ * Implements hook_uuid_entities_features_export_entity_alter().
  */
  */
 function user_uuid_entities_features_export_entity_alter(&$entity, $entity_type) {
 function user_uuid_entities_features_export_entity_alter(&$entity, $entity_type) {
-  if ($entity_type == 'user') {
-    foreach (array('data', 'access', 'login') as $property) {
-      if (property_exists($entity, $property)) {
-        unset($entity->{$property});
-      }
+  if ('user' != $entity_type) {
+    return;
+  }
+
+  foreach (array('data', 'access', 'login') as $property) {
+    if (property_exists($entity, $property)) {
+      unset($entity->{$property});
     }
     }
   }
   }
 }
 }
@@ -391,17 +438,6 @@ function file_uuid_entities_features_export_field_alter($entity_type, $entity, $
   }
   }
 }
 }
 
 
-/**
- * Implements hook_uuid_entities_features_export_entity_alter().
- */
-function workbench_uuid_entities_features_export_entity_alter(&$entity, $entity_type) {
-  foreach (array('workbench_moderation', 'my_revision', 'workbench_access', 'workbench_access_scheme', 'workbench_access_by_role') as $property) {
-    if (isset($entity->{$property})) {
-      unset($entity->{$property});
-    }
-  }
-}
-
 /**
 /**
  * @} End of "Export alterations"
  * @} End of "Export alterations"
  */
  */

+ 2 - 2
sites/all/modules/uuid/uuid.drush.inc

@@ -6,7 +6,7 @@
  */
  */
 
 
 /**
 /**
- * Implementats hook_drush_command().
+ * Implements hook_drush_command().
  */
  */
 function uuid_drush_command() {
 function uuid_drush_command() {
   $items = array();
   $items = array();
@@ -18,7 +18,7 @@ function uuid_drush_command() {
 }
 }
 
 
 /**
 /**
- * Implementats of hook_drush_help().
+ * Implements hook_drush_help().
  */
  */
 function uuid_drush_help($section) {
 function uuid_drush_help($section) {
   switch ($section) {
   switch ($section) {

+ 132 - 38
sites/all/modules/uuid/uuid.entity.inc

@@ -11,8 +11,7 @@
 class UuidEntityException extends Exception {}
 class UuidEntityException extends Exception {}
 
 
 /**
 /**
- * Helper function that returns entity info for all supported core modules,
- * relevant for UUID functionality.
+ * Returns entity info for all supported core entities.
  *
  *
  * @see uuid_entity_info()
  * @see uuid_entity_info()
  * @see uuid_schema_alter()
  * @see uuid_schema_alter()
@@ -76,9 +75,9 @@ function uuid_get_core_entity_info() {
  */
  */
 
 
 /**
 /**
- * Implements of hook_entity_info_alter().
+ * Implements hook_entity_info_alter().
  *
  *
- * @see uuid_core_entity_info().
+ * @see uuid_core_entity_info()
  */
  */
 function uuid_entity_info_alter(&$info) {
 function uuid_entity_info_alter(&$info) {
   foreach (uuid_get_core_entity_info() as $entity_type => $core_info) {
   foreach (uuid_get_core_entity_info() as $entity_type => $core_info) {
@@ -91,21 +90,24 @@ function uuid_entity_info_alter(&$info) {
 }
 }
 
 
 /**
 /**
- * Implements of hook_entity_property_info_alter().
+ * Implements hook_entity_property_info_alter().
  *
  *
  * This adds the UUID as an entity property for all UUID-enabled entities
  * This adds the UUID as an entity property for all UUID-enabled entities
  * which automatically gives us token and Rules integration.
  * which automatically gives us token and Rules integration.
  */
  */
 function uuid_entity_property_info_alter(&$info) {
 function uuid_entity_property_info_alter(&$info) {
   foreach (entity_get_info() as $entity_type => $entity_info) {
   foreach (entity_get_info() as $entity_type => $entity_info) {
-    if (isset($entity_info['uuid']) && $entity_info['uuid'] == TRUE && !empty($entity_info['entity keys']['uuid'])) {
+    if (isset($entity_info['uuid']) && $entity_info['uuid'] == TRUE
+      && !empty($entity_info['entity keys']['uuid'])
+      && empty($info[$entity_type]['properties'][$entity_info['entity keys']['uuid']])) {
       $info[$entity_type]['properties'][$entity_info['entity keys']['uuid']] = array(
       $info[$entity_type]['properties'][$entity_info['entity keys']['uuid']] = array(
         'label' => t('UUID'),
         'label' => t('UUID'),
         'type' => 'text',
         'type' => 'text',
         'description' => t('The universally unique ID.'),
         'description' => t('The universally unique ID.'),
         'schema field' => $entity_info['entity keys']['uuid'],
         'schema field' => $entity_info['entity keys']['uuid'],
       );
       );
-      if (!empty($entity_info['entity keys']['revision uuid'])) {
+      if (!empty($entity_info['entity keys']['revision uuid'])
+        && empty($info[$entity_type]['properties'][$entity_info['entity keys']['revision uuid']])) {
         $info[$entity_type]['properties'][$entity_info['entity keys']['revision uuid']] = array(
         $info[$entity_type]['properties'][$entity_info['entity keys']['revision uuid']] = array(
           'label' => t('Revision UUID'),
           'label' => t('Revision UUID'),
           'type' => 'text',
           'type' => 'text',
@@ -118,7 +120,7 @@ function uuid_entity_property_info_alter(&$info) {
 }
 }
 
 
 /**
 /**
- * Implements of hook_entity_presave().
+ * Implements hook_entity_presave().
  *
  *
  * This is where all UUID-enabled entities get their UUIDs.
  * This is where all UUID-enabled entities get their UUIDs.
  */
  */
@@ -131,7 +133,19 @@ function uuid_entity_presave($entity, $entity_type) {
     }
     }
     if (!empty($info['entity keys']['revision uuid'])) {
     if (!empty($info['entity keys']['revision uuid'])) {
       $vuuid_key = $info['entity keys']['revision uuid'];
       $vuuid_key = $info['entity keys']['revision uuid'];
-      if ((isset($entity->revision) && $entity->revision == TRUE) || empty($entity->{$vuuid_key})) {
+      // If this entity comes from a remote environment and have a revision UUID
+      // that exists locally we should not create a new revision. Because
+      // otherwise revisions won't be tracked universally.
+      // TODO: Move code dependent on the uuid_services module into it's own
+      // implementation of hook_entity_presave().
+      if (!empty($entity->uuid_services) && isset($entity->{$vuuid_key})) {
+        $vuuid_exists = (bool) entity_get_id_by_uuid($entity_type, array($entity->{$vuuid_key}), TRUE);
+        if ($vuuid_exists) {
+          $entity->revision = FALSE;
+        }
+      }
+
+      if ((isset($entity->revision) && $entity->revision == TRUE && empty($entity->uuid_services)) || empty($entity->{$vuuid_key})) {
         $entity->{$vuuid_key} = uuid_generate();
         $entity->{$vuuid_key} = uuid_generate();
       }
       }
     }
     }
@@ -151,12 +165,26 @@ function uuid_entity_presave($entity, $entity_type) {
 /**
 /**
  * Load entities by their UUID, that only should containing UUID references.
  * Load entities by their UUID, that only should containing UUID references.
  *
  *
+ * Optionally load revisions by their VUUID by passing it into $conditions.
+ * Ex. $conditions['vuuid'][$vuuid]
+ *
  * This function is mostly useful if you want to load an entity from the local
  * This function is mostly useful if you want to load an entity from the local
  * database that only should contain UUID references.
  * database that only should contain UUID references.
  *
  *
  * @see entity_load()
  * @see entity_load()
  */
  */
 function entity_uuid_load($entity_type, $uuids = array(), $conditions = array(), $reset = FALSE) {
 function entity_uuid_load($entity_type, $uuids = array(), $conditions = array(), $reset = FALSE) {
+  // Allow Revision UUID to be passed in $conditions and translate.
+  $entity_info[$entity_type] = entity_get_info($entity_type);
+  $revision_key = $entity_info[$entity_type]['entity keys']['revision'];
+  if (isset($entity_info[$entity_type]['entity keys']['revision uuid'])) {
+    $revision_uuid_key = $entity_info[$entity_type]['entity keys']['revision uuid'];
+  }
+  if (isset($revision_uuid_key) && isset($conditions[$revision_uuid_key])) {
+    $revision_id = entity_get_id_by_uuid($entity_type, array($conditions[$revision_uuid_key]), TRUE);
+    $conditions[$revision_key] = $revision_id[$conditions[$revision_uuid_key]];
+    unset($conditions[$revision_uuid_key]);
+  }
   $ids = entity_get_id_by_uuid($entity_type, $uuids);
   $ids = entity_get_id_by_uuid($entity_type, $uuids);
   $results = entity_load($entity_type, $ids, $conditions, $reset);
   $results = entity_load($entity_type, $ids, $conditions, $reset);
   $entities = array();
   $entities = array();
@@ -209,10 +237,27 @@ function entity_uuid_save($entity_type, $entity) {
     throw new UuidEntityException(t('Calling %function requires the Entity API module (!link).', array('%function' => __FUNCTION__, '!link' => 'http://drupal.org/project/entity')));
     throw new UuidEntityException(t('Calling %function requires the Entity API module (!link).', array('%function' => __FUNCTION__, '!link' => 'http://drupal.org/project/entity')));
   }
   }
 
 
+  $info = entity_get_info($entity_type);
+  $uuid_key = $info['entity keys']['uuid'];
+  if (empty($entity->{$uuid_key}) || !uuid_is_valid($entity->{$uuid_key})) {
+    watchdog('Entity UUID', 'Attempted to save an entity with an invalid UUID', array(), WATCHDOG_ERROR);
+    return FALSE;
+  }
+
+  // Falling back on the variable node_options_[type] is not something an API
+  // function should take care of. With normal (non UUID) nodes this is dealt
+  // with in the form submit handler, i.e. not in node_save().
+  // But since using entity_uuid_save() usually means you're trying to manage
+  // entities remotely we do respect this variable here to make it work as the
+  // node form, but only if we explicitly haven't set $node->revision already.
+  if ($entity_type == 'node' && !isset($entity->revision) && in_array('revision', variable_get('node_options_' . $entity->type, array()))) {
+    $entity->revision = 1;
+  }
+
   entity_make_entity_local($entity_type, $entity);
   entity_make_entity_local($entity_type, $entity);
 
 
   // Save the entity.
   // Save the entity.
-  entity_save($entity_type, $entity);
+  $result = entity_save($entity_type, $entity);
 
 
   $hook = 'entity_uuid_save';
   $hook = 'entity_uuid_save';
   foreach (module_implements($hook) as $module) {
   foreach (module_implements($hook) as $module) {
@@ -221,6 +266,7 @@ function entity_uuid_save($entity_type, $entity) {
       $function($entity, $entity_type);
       $function($entity, $entity_type);
     }
     }
   }
   }
+  return $result;
 }
 }
 
 
 /**
 /**
@@ -259,6 +305,10 @@ function entity_make_entity_local($entity_type, $entity) {
       $vid = NULL;
       $vid = NULL;
       // Fetch the local revision ID by its UUID.
       // Fetch the local revision ID by its UUID.
       if (isset($entity->{$vuuid_key})) {
       if (isset($entity->{$vuuid_key})) {
+        // It's important to note that the revision UUID might be set here but
+        // there might not exist a correspondant local revision ID in which case
+        // we should unset the assigned revision ID to not confuse anyone with
+        // revision IDs that might come from other environments.
         $vids = entity_get_id_by_uuid($entity_type, array($entity->{$vuuid_key}), TRUE);
         $vids = entity_get_id_by_uuid($entity_type, array($entity->{$vuuid_key}), TRUE);
         $vid = reset($vids);
         $vid = reset($vids);
       }
       }
@@ -268,9 +318,10 @@ function entity_make_entity_local($entity_type, $entity) {
       elseif (!empty($vid)) {
       elseif (!empty($vid)) {
         $entity->{$vid_key} = $vid;
         $entity->{$vid_key} = $vid;
       }
       }
-      // Nodes need this when trying to save an existing node without a vid.
+      // If the revision ID was unset before this (or just missing for some
+      // reason) we fetch the current revision ID to build a better
+      // representation of the node object we're working with.
       if ($entity_type == 'node' && !isset($entity->vid) && !$entity->is_new) {
       if ($entity_type == 'node' && !isset($entity->vid) && !$entity->is_new) {
-        $entity->revision = 0;
         $entity->vid = db_select('node', 'n')
         $entity->vid = db_select('node', 'n')
           ->condition('n.nid', $entity->nid)
           ->condition('n.nid', $entity->nid)
           ->fields('n', array('vid'))
           ->fields('n', array('vid'))
@@ -289,7 +340,7 @@ function entity_make_entity_local($entity_type, $entity) {
     }
     }
   }
   }
   else {
   else {
-    throw new UuidEntityException(t('Trying to operate on a @type entity, which doesn\'t support UUIDs.', array('@type' => $info['label'])));
+    throw new UuidEntityException(t("Trying to operate on a @type entity, which doesn\'t support UUIDs.", array('@type' => $info['label'])));
   }
   }
 }
 }
 
 
@@ -312,6 +363,7 @@ function entity_uuid_delete($entity_type, $uuid) {
     // Fetch the local ID by its UUID.
     // Fetch the local ID by its UUID.
     $ids = entity_get_id_by_uuid($entity_type, array($uuid));
     $ids = entity_get_id_by_uuid($entity_type, array($uuid));
     $id = reset($ids);
     $id = reset($ids);
+    $entity = entity_load($entity_type, array($id));
 
 
     // Let other modules transform UUID references to local ID references.
     // Let other modules transform UUID references to local ID references.
     $hook = 'entity_uuid_delete';
     $hook = 'entity_uuid_delete';
@@ -322,11 +374,14 @@ function entity_uuid_delete($entity_type, $uuid) {
       }
       }
     }
     }
 
 
+    if (empty($entity)) {
+      return FALSE;
+    }
     // Delete the entity.
     // Delete the entity.
     return entity_delete($entity_type, $id);
     return entity_delete($entity_type, $id);
   }
   }
   else {
   else {
-    throw new UuidEntityException(t('Trying to delete a @type entity, which doesn\'t support UUIDs.', array('@type' => $info['label'])));
+    throw new UuidEntityException(t("Trying to delete a @type entity, which doesn\'t support UUIDs.", array('@type' => $info['label'])));
   }
   }
 }
 }
 
 
@@ -334,24 +389,34 @@ function entity_uuid_delete($entity_type, $uuid) {
  * Helper function that retrieves entity IDs by their UUIDs.
  * Helper function that retrieves entity IDs by their UUIDs.
  *
  *
  * @todo
  * @todo
- *   Statically cache as many IDs as possible and limit the query.
+ *   Limit the query.
  *
  *
- * @param $entity_type
+ * @param string $entity_type
  *   The entity type we should be dealing with.
  *   The entity type we should be dealing with.
- * @param $uuids
- *   An array of UUIDs for which we should find their entity IDs. If $revision
+ * @param array $uuids
+ *   List of UUIDs for which we should find their entity IDs. If $revision
  *   is TRUE this should be revision UUIDs instead.
  *   is TRUE this should be revision UUIDs instead.
- * @param $revision
+ * @param bool $revision
  *   If TRUE the revision IDs is returned instead.
  *   If TRUE the revision IDs is returned instead.
- * @return
- *   Array of entity IDs keyed by their UUIDs. If $revision is TRUE revision
+ *
+ * @return array
+ *   List of entity IDs keyed by their UUIDs. If $revision is TRUE revision
  *   IDs and UUIDs are returned instead.
  *   IDs and UUIDs are returned instead.
  */
  */
 function entity_get_id_by_uuid($entity_type, $uuids, $revision = FALSE) {
 function entity_get_id_by_uuid($entity_type, $uuids, $revision = FALSE) {
   if (empty($uuids)) {
   if (empty($uuids)) {
     return array();
     return array();
   }
   }
+  $cached_ids = entity_uuid_id_cache($entity_type, $uuids, $revision);
+  if (count($cached_ids) == count($uuids)) {
+    return $cached_ids;
+  }
+  $uuids = array_diff($uuids, $cached_ids);
   $info = entity_get_info($entity_type);
   $info = entity_get_info($entity_type);
+  // Some contrib entities has no support for UUID, let's skip them.
+  if (empty($info['uuid'])) {
+    return array();
+  }
   // Find out what entity keys to use.
   // Find out what entity keys to use.
   if (!$revision) {
   if (!$revision) {
     $table = $info['base table'];
     $table = $info['base table'];
@@ -369,35 +434,61 @@ function entity_get_id_by_uuid($entity_type, $uuids, $revision = FALSE) {
   }
   }
 
 
   // Get all UUIDs in one query.
   // Get all UUIDs in one query.
-  return db_select($table, 't')
+  $result = db_select($table, 't')
     ->fields('t', array($uuid_key, $id_key))
     ->fields('t', array($uuid_key, $id_key))
     ->condition($uuid_key, array_values($uuids), 'IN')
     ->condition($uuid_key, array_values($uuids), 'IN')
     ->execute()
     ->execute()
     ->fetchAllKeyed();
     ->fetchAllKeyed();
+  $cache = &drupal_static('entity_uuid_id_cache', array());
+  $cache[$entity_type][(int) $revision] += $result;
+  return $result + $cached_ids;
+}
+
+/**
+ * Helper caching function.
+ */
+function entity_uuid_id_cache($entity_type, $ids, $revision) {
+  $cache = &drupal_static(__FUNCTION__, array());
+  if (empty($cache[$entity_type][(int) $revision])) {
+    $cache[$entity_type][(int) $revision] = array();
+  }
+  $cached_ids = $cache[$entity_type][(int) $revision];
+  return array_intersect_key($cached_ids, array_flip($ids));
 }
 }
 
 
 /**
 /**
  * Helper function that retrieves UUIDs by their entity IDs.
  * Helper function that retrieves UUIDs by their entity IDs.
  *
  *
  * @todo
  * @todo
- *   Statically cache as many IDs as possible and limit the query.
+ *   Limit the query.
  *
  *
- * @param $entity_type
+ * @param string $entity_type
  *   The entity type we should be dealing with.
  *   The entity type we should be dealing with.
- * @param $ids
- *   An array of entity IDs for which we should find their UUIDs. If $revision
+ * @param array $ids
+ *   List of entity IDs for which we should find their UUIDs. If $revision
  *   is TRUE this should be revision IDs instead.
  *   is TRUE this should be revision IDs instead.
- * @param $revision
+ * @param bool $revision
  *   If TRUE the revision UUIDs is returned instead.
  *   If TRUE the revision UUIDs is returned instead.
- * @return
- *   Array of entity UUIDs keyed by their IDs. If $revision is TRUE revision
+ *
+ * @return array
+ *   List of entity UUIDs keyed by their IDs. If $revision is TRUE revision
  *   IDs and UUIDs are returned instead.
  *   IDs and UUIDs are returned instead.
  */
  */
 function entity_get_uuid_by_id($entity_type, $ids, $revision = FALSE) {
 function entity_get_uuid_by_id($entity_type, $ids, $revision = FALSE) {
   if (empty($ids)) {
   if (empty($ids)) {
     return array();
     return array();
   }
   }
+  $cached_ids = array_flip(entity_uuid_id_cache($entity_type, $ids, $revision));
+  if (count($cached_ids) == count($ids)) {
+    return $cached_ids;
+  }
+  $ids = array_diff($ids, $cached_ids);
+
   $info = entity_get_info($entity_type);
   $info = entity_get_info($entity_type);
+  // Some contrib entities has no support for UUID, let's skip them.
+  if (empty($info['uuid'])) {
+    return array();
+  }
   // Find out what entity keys to use.
   // Find out what entity keys to use.
   if (!$revision) {
   if (!$revision) {
     $table = $info['base table'];
     $table = $info['base table'];
@@ -415,11 +506,14 @@ function entity_get_uuid_by_id($entity_type, $ids, $revision = FALSE) {
   }
   }
 
 
   // Get all UUIDs in one query.
   // Get all UUIDs in one query.
-  return db_select($table, 't')
+  $result = db_select($table, 't')
     ->fields('t', array($id_key, $uuid_key))
     ->fields('t', array($id_key, $uuid_key))
     ->condition($id_key, array_values($ids), 'IN')
     ->condition($id_key, array_values($ids), 'IN')
     ->execute()
     ->execute()
     ->fetchAllKeyed();
     ->fetchAllKeyed();
+  $cache = &drupal_static('entity_uuid_id_cache', array());
+  $cache[$entity_type][(int) $revision] += array_flip($result);
+  return $result + $cached_ids;
 }
 }
 
 
 /**
 /**
@@ -432,12 +526,12 @@ function entity_get_uuid_by_id($entity_type, $ids, $revision = FALSE) {
  * @todo
  * @todo
  *   Add tests for this function.
  *   Add tests for this function.
  *
  *
- * @param $objects
- *   An array of objects that should get $properties changed. Can be either an
+ * @param array $objects
+ *   List of objects that should get $properties changed. Can be either an
  *   entity object or a field items array.
  *   entity object or a field items array.
- * @param $entity_type
+ * @param string $entity_type
  *   The type of entity that all $properties refers to.
  *   The type of entity that all $properties refers to.
- * @param $properties
+ * @param array $properties
  *   An array of properties that should be changed. All properties must refer to
  *   An array of properties that should be changed. All properties must refer to
  *   the same type of entity (the one referenced in $entity_type).
  *   the same type of entity (the one referenced in $entity_type).
  */
  */
@@ -488,12 +582,12 @@ function entity_property_id_to_uuid(&$objects, $entity_type, $properties) {
  * @todo
  * @todo
  *   Add tests for this function.
  *   Add tests for this function.
  *
  *
- * @param $objects
- *   An array of objects that should get $properties changed. Can be either an
+ * @param array $objects
+ *   List of objects that should get $properties changed. Can be either an
  *   entity object or a field items array.
  *   entity object or a field items array.
- * @param $entity_type
+ * @param string $entity_type
  *   The type of entity that all $properties refers to.
  *   The type of entity that all $properties refers to.
- * @param $properties
+ * @param array $properties
  *   An array of properties that should be changed. All properties must refer to
  *   An array of properties that should be changed. All properties must refer to
  *   the same type of entity (the one referenced in $entity_type).
  *   the same type of entity (the one referenced in $entity_type).
  */
  */

+ 17 - 5
sites/all/modules/uuid/uuid.features.inc

@@ -84,7 +84,15 @@ function uuid_entities_features_export_render($module_name, $components, $export
       }
       }
       // We unset some common timestamp properties, since those will change and
       // We unset some common timestamp properties, since those will change and
       // constantly leave the feature overidden.
       // constantly leave the feature overidden.
-      $keys = array('created', 'updated', 'changed', 'revision_timestamp', 'timestamp', 'stamp', 'current');
+      $keys = array(
+        'created',
+        'updated',
+        'changed',
+        'revision_timestamp',
+        'timestamp',
+        'stamp',
+        'current',
+      );
       foreach ($keys as $key) {
       foreach ($keys as $key) {
         if (isset($entity->{$key})) {
         if (isset($entity->{$key})) {
           unset($entity->{$key});
           unset($entity->{$key});
@@ -93,7 +101,7 @@ function uuid_entities_features_export_render($module_name, $components, $export
       // Let other modules alter exported entities.
       // Let other modules alter exported entities.
       drupal_alter('uuid_entities_features_export_entity', $entity, $entity_type);
       drupal_alter('uuid_entities_features_export_entity', $entity, $entity_type);
       // Field handling.
       // Field handling.
-      list(,, $bundle_name) = entity_extract_ids($entity_type, $entity);
+      list(, , $bundle_name) = entity_extract_ids($entity_type, $entity);
       $instances = field_info_instances($entity_type, $bundle_name);
       $instances = field_info_instances($entity_type, $bundle_name);
       foreach ($instances as $field_name => $instance) {
       foreach ($instances as $field_name => $instance) {
         $field = field_info_field($field_name);
         $field = field_info_field($field_name);
@@ -121,7 +129,10 @@ function uuid_entities_features_export_render($module_name, $components, $export
       }
       }
       uuid_entities_features_clean($entity);
       uuid_entities_features_clean($entity);
 
 
-      // Convert entities to array to avoid having them in JSON, returned from standard implementation of $entity->export().
+      /*
+       * Convert entities to array to avoid having them in JSON, returned
+       * from standard implementation of $entity->export().
+       */
       if (is_object($entity) && method_exists($entity, 'export')) {
       if (is_object($entity) && method_exists($entity, 'export')) {
         $entity = get_object_vars($entity);
         $entity = get_object_vars($entity);
       }
       }
@@ -134,14 +145,14 @@ function uuid_entities_features_export_render($module_name, $components, $export
 }
 }
 
 
 /**
 /**
- * Implements [component]_features_export_rebuild().
+ * Implements [component]_features_rebuild().
  */
  */
 function uuid_entities_features_rebuild($module_name) {
 function uuid_entities_features_rebuild($module_name) {
   uuid_entities_rebuild($module_name, 'rebuild');
   uuid_entities_rebuild($module_name, 'rebuild');
 }
 }
 
 
 /**
 /**
- * Implements [component]_features_export_revert().
+ * Implements [component]_features_revert().
  */
  */
 function uuid_entities_features_revert($module_name) {
 function uuid_entities_features_revert($module_name) {
   uuid_entities_rebuild($module_name, 'revert');
   uuid_entities_rebuild($module_name, 'revert');
@@ -157,6 +168,7 @@ function uuid_entities_rebuild($module_name = '', $op = 'rebuild') {
     foreach ($entities as $plan_name => $entities) {
     foreach ($entities as $plan_name => $entities) {
       // Let other modules do things before default entities are created.
       // Let other modules do things before default entities are created.
       module_invoke_all("uuid_entities_pre_$op", $plan_name);
       module_invoke_all("uuid_entities_pre_$op", $plan_name);
+      drupal_alter("uuid_entities_pre_$op", $entities, $plan_name);
       foreach ($entities as $entity) {
       foreach ($entities as $entity) {
         entity_uuid_save($entity->__metadata['type'], $entity);
         entity_uuid_save($entity->__metadata['type'], $entity);
       }
       }

+ 112 - 41
sites/all/modules/uuid/uuid.inc

@@ -8,7 +8,7 @@
 /**
 /**
  * Pattern for detecting a valid UUID.
  * Pattern for detecting a valid UUID.
  */
  */
-define('UUID_PATTERN', '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}');
+define('UUID_PATTERN', '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}');
 
 
 /**
 /**
  * Generates an universally unique identifier.
  * Generates an universally unique identifier.
@@ -17,7 +17,7 @@ define('UUID_PATTERN', '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}');
  * universally unique identifiers. If that doesn't exist, then it falls back on
  * universally unique identifiers. If that doesn't exist, then it falls back on
  * PHP for generating that.
  * PHP for generating that.
  *
  *
- * @return
+ * @return string
  *   An UUID, made up of 32 hex digits and 4 hyphens.
  *   An UUID, made up of 32 hex digits and 4 hyphens.
  */
  */
 function uuid_generate() {
 function uuid_generate() {
@@ -37,6 +37,61 @@ function uuid_generate() {
   return $callback();
   return $callback();
 }
 }
 
 
+/**
+ * Generates a version 5 compliant UUID.
+ *
+ * @param string $namespace
+ *   Namespace UUID as a hex encoded string.
+ * @param string $name
+ *   The name for the generating the UUID.
+ *
+ * @return string
+ *   UUID as a hex encoded string.
+ *
+ * @link http://www.php.net/manual/en/function.uniqid.php#94959 Code lifted from
+ * PHP manual comment by Andrew Moore. @endlink
+ */
+function uuid_generate_v5($namespace, $name) {
+  if (!uuid_is_valid($namespace)) {
+    return FALSE;
+  }
+
+  // Get hexadecimal components of namespace.
+  $nhex = str_replace(array('-', '{', '}'), '', $namespace);
+
+  // Binary Value.
+  $nstr = '';
+
+  // Convert Namespace UUID to bits.
+  for ($i = 0; $i < strlen($nhex); $i += 2) {
+    $nstr .= chr(hexdec($nhex[$i] . $nhex[$i + 1]));
+  }
+
+  // Calculate hash value.
+  $hash = sha1($nstr . $name);
+
+  return sprintf('%08s-%04s-%04x-%04x-%12s',
+
+    // 32 bits for "time_low".
+    substr($hash, 0, 8),
+
+    // 16 bits for "time_mid".
+    substr($hash, 8, 4),
+
+    // 16 bits for "time_hi_and_version",
+    // four most significant bits holds version number 5.
+    (hexdec(substr($hash, 12, 4)) & 0x0fff) | 0x5000,
+
+    // 16 bits, 8 bits for "clk_seq_hi_res",
+    // 8 bits for "clk_seq_low",
+    // two most significant bits holds zero and one for variant DCE1.1.
+    (hexdec(substr($hash, 16, 4)) & 0x3fff) | 0x8000,
+
+    // 48 bits for "node".
+    substr($hash, 20, 12)
+  );
+}
+
 /**
 /**
  * Generate all missing UUIDs.
  * Generate all missing UUIDs.
  */
  */
@@ -53,7 +108,7 @@ function uuid_sync_all() {
  *   The type of entity being used.
  *   The type of entity being used.
  *
  *
  * @return string
  * @return string
- *  The generated UUID URI or normal URI if entity doesn't support UUIDs.
+ *   The generated UUID URI or normal URI if entity doesn't support UUIDs.
  */
  */
 function uuid_entity_uuid_uri($entity, $entity_type) {
 function uuid_entity_uuid_uri($entity, $entity_type) {
   $entity_info = entity_get_info($entity_type);
   $entity_info = entity_get_info($entity_type);
@@ -73,13 +128,13 @@ function uuid_entity_uuid_uri($entity, $entity_type) {
 /**
 /**
  * Converts an ID URI string to an entity data array.
  * Converts an ID URI string to an entity data array.
  *
  *
- * @see uuid_id_uri_array_to_data()
- *
  * @param string $uri
  * @param string $uri
- *  The URI to convert.
+ *   The URI to convert.
  *
  *
  * @return array
  * @return array
- *  The entity data.
+ *   The entity data.
+ *
+ * @see uuid_id_uri_array_to_data()
  */
  */
 function uuid_id_uri_to_data($uri) {
 function uuid_id_uri_to_data($uri) {
   $parts = explode('/', $uri);
   $parts = explode('/', $uri);
@@ -90,10 +145,10 @@ function uuid_id_uri_to_data($uri) {
  * Converts a URI array to entity data array.
  * Converts a URI array to entity data array.
  *
  *
  * @param array $uri
  * @param array $uri
- *  The URI parts, often taken from arg().
+ *   The URI parts, often taken from arg().
  *
  *
  * @return array
  * @return array
- *  The entity data.
+ *   The entity data.
  */
  */
 function uuid_id_uri_array_to_data($uri) {
 function uuid_id_uri_array_to_data($uri) {
   $data = array(
   $data = array(
@@ -110,13 +165,13 @@ function uuid_id_uri_array_to_data($uri) {
 /**
 /**
  * Converts a UUID URI string to an entity data array.
  * Converts a UUID URI string to an entity data array.
  *
  *
- * @see uuid_uri_array_to_data()
- *
  * @param string $uri
  * @param string $uri
- *  The URI to convert.
+ *   The URI to convert.
  *
  *
  * @return array
  * @return array
- *  The entity data.
+ *   The entity data.
+ *
+ * @see uuid_uri_array_to_data()
  */
  */
 function uuid_uri_to_data($uri, $strip_uuid = TRUE) {
 function uuid_uri_to_data($uri, $strip_uuid = TRUE) {
   return uuid_uri_array_to_data(explode('/', $uri));
   return uuid_uri_array_to_data(explode('/', $uri));
@@ -126,10 +181,10 @@ function uuid_uri_to_data($uri, $strip_uuid = TRUE) {
  * Converts a URI array to entity data array.
  * Converts a URI array to entity data array.
  *
  *
  * @param array $uri
  * @param array $uri
- *  The URI parts, often taken from arg().
+ *   The URI parts, often taken from arg().
  *
  *
  * @return array
  * @return array
- *  The entity data.
+ *   The entity data.
  */
  */
 function uuid_uri_array_to_data($uri, $strip_uuid = TRUE) {
 function uuid_uri_array_to_data($uri, $strip_uuid = TRUE) {
   if ($strip_uuid) {
   if ($strip_uuid) {
@@ -138,8 +193,8 @@ function uuid_uri_array_to_data($uri, $strip_uuid = TRUE) {
 
 
   $data = array(
   $data = array(
     'request' => $uri,
     'request' => $uri,
-    'entity_type' => $uri[0],
-    'uuid' => $uri[1],
+    'entity_type' => isset($uri[0]) ? $uri[0] : NULL,
+    'uuid' => isset($uri[1]) ? $uri[1] : NULL,
   );
   );
 
 
   drupal_alter('uuid_uri_data', $data);
   drupal_alter('uuid_uri_data', $data);
@@ -165,40 +220,56 @@ function _uuid_generate_pecl() {
 }
 }
 
 
 /**
 /**
- * Generates a UUID v4 using PHP code.
- * 
- * Based on code from @see http://php.net/uniqid#65879 , but corrected.
+ * Generates a UUID v4 (RFC 4122 section 4.4) using PHP code.
+ *
+ * @see http://www.rfc-editor.org/rfc/rfc4122.txt
+ *
+ * The UUID layout and fields are defined in section 4.1.2.
+ *
+ * Note that there are inconsistencies in the RFC with respect to
+ * bit numbering. Network Order is correct, so the most significant bit
+ * always appears first (in left-to-right sequence). See errata 3546:
+ * http://www.rfc-editor.org/errata_search.php?rfc=4122&eid=3546
+ *
+ * Based on code from http://php.net/uniqid
  */
  */
 function _uuid_generate_php() {
 function _uuid_generate_php() {
-  // The field names refer to RFC 4122 section 4.1.2.
+  // We limit each generated number to 16 bits (maximum value 0xffff)
+  // because mt_rand() returns a *signed* integer, and hence a 32-bit
+  // value can only have a 31-bit magnitude. Constructing a 32-bit
+  // number from two 16-bit random numbers guarantees that all 32 bits
+  // are random.
   return sprintf('%04x%04x-%04x-4%03x-%04x-%04x%04x%04x',
   return sprintf('%04x%04x-%04x-4%03x-%04x-%04x%04x%04x',
     // 32 bits for "time_low".
     // 32 bits for "time_low".
-    mt_rand(0, 65535), mt_rand(0, 65535),
+    mt_rand(0, 0xffff), mt_rand(0, 0xffff),
     // 16 bits for "time_mid".
     // 16 bits for "time_mid".
-    mt_rand(0, 65535),
-    // 12 bits after the 0100 of (version) 4 for "time_hi_and_version".
-    mt_rand(0, 4095),
-    bindec(substr_replace(sprintf('%016b', mt_rand(0, 65535)), '10', 0, 2)),
-    // 8 bits, the last two of which (positions 6 and 7) are 01, for "clk_seq_hi_res"
-    // (hence, the 2nd hex digit after the 3rd hyphen can only be 1, 5, 9 or d)
-    // 8 bits for "clk_seq_low" 48 bits for "node".
-    mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535)
+    mt_rand(0, 0xffff),
+    // 12 bits after the initial 0100 (version 4) for "time_hi_and_version".
+    mt_rand(0, 0x0fff),
+    // 16 bits in total for "clk_seq_hi_res" and "clk_seq_low", with the
+    // most significant 2 bits of clk_seq_hi_res set to '10'. We do a
+    // bitwise OR of a random 14-bit value (maximum 0x3fff) with 0x8000
+    // (a 16-bit integer with only the most significant bit set).
+    mt_rand(0, 0x3fff) | 0x8000,
+    // 48 bits for "node".
+    mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
   );
   );
 }
 }
 
 
-
-// This is wrapped in an if block to avoid conflicts with PECL's uuid_is_valid().
-/**
- * Check that a string appears to be in the format of a UUID.
- *
- * @param $uuid
- *  The string to test.
- *
- * @return
- *   TRUE if the string is well formed.
- */
+// The if block avoids conflicts with PECL's uuid_is_valid().
 if (!function_exists('uuid_is_valid')) {
 if (!function_exists('uuid_is_valid')) {
+
+  /**
+   * Check that a string appears to be in the format of a UUID.
+   *
+   * @param string $uuid
+   *   The string to test.
+   *
+   * @return bool
+   *    TRUE if the string is well formed.
+   */
   function uuid_is_valid($uuid) {
   function uuid_is_valid($uuid) {
     return preg_match('/^' . UUID_PATTERN . '$/', $uuid);
     return preg_match('/^' . UUID_PATTERN . '$/', $uuid);
   }
   }
+
 }
 }

+ 5 - 4
sites/all/modules/uuid/uuid.info

@@ -4,10 +4,11 @@ core = 7.x
 package = UUID
 package = UUID
 configure = admin/config/system/uuid
 configure = admin/config/system/uuid
 files[] = uuid.test
 files[] = uuid.test
+dependencies[] = node
+dependencies[] = user
 
 
-; Information added by drupal.org packaging script on 2013-02-03
-version = "7.x-1.0-alpha3+52-dev"
+; Information added by Drupal.org packaging script on 2018-07-19
+version = "7.x-1.2"
 core = "7.x"
 core = "7.x"
 project = "uuid"
 project = "uuid"
-datestamp = "1359858369"
-
+datestamp = "1531990689"

+ 83 - 22
sites/all/modules/uuid/uuid.install

@@ -29,14 +29,28 @@ function uuid_schema_field_definition() {
 }
 }
 
 
 /**
 /**
- * Implements of hook_schema_alter().
+ * Implements hook_schema_alter().
  */
  */
-function uuid_schema_alter(&$schema = array()) {
-  $field = uuid_schema_field_definition();
-  foreach (uuid_get_core_entity_info() as $entity_type => $info) {
-    $schema[$info['base table']]['fields'][$info['entity keys']['uuid']] = $field;
-    if (!empty($info['revision table']) && !empty($info['entity keys']['revision uuid'])) {
-      $schema[$info['revision table']]['fields'][$info['entity keys']['revision uuid']] = $field;
+function uuid_schema_alter(array &$schema) {
+  $field_info = uuid_schema_field_definition();
+  $key_names = array(
+    'base table' => 'uuid',
+    'revision table' => 'revision uuid',
+  );
+
+  foreach (uuid_get_core_entity_info() as $entity_info) {
+    foreach ($key_names as $table_type => $key_name) {
+      if (isset($entity_info[$table_type], $entity_info['entity keys'][$key_name])) {
+        $field_name = $entity_info['entity keys'][$key_name];
+        $properties = array(
+          'fields' => $field_info,
+          'indexes' => array($field_name),
+        );
+
+        foreach ($properties as $property => $value) {
+          $schema[$entity_info[$table_type]][$property][$field_name] = $value;
+        }
+      }
     }
     }
   }
   }
 }
 }
@@ -46,19 +60,20 @@ function uuid_schema_alter(&$schema = array()) {
  */
  */
 function uuid_install() {
 function uuid_install() {
   _uuid_install_uuid_fields();
   _uuid_install_uuid_fields();
+  module_load_include('inc', 'uuid');
   uuid_sync_all();
   uuid_sync_all();
 }
 }
 
 
 /**
 /**
- * Install the 'uuid' and 'vuuid' fields into Drupal core entity tables where needed.
+ * Install the uuid and vuuid fields for Drupal core entity tables where needed.
  *
  *
- * IMPORTANT:  This function is called both at install and update time.  If this method
- * is modified to add additional fields in the future, the update strategy must be
- * considered.  See the comment in uuid_update_7102.
+ * IMPORTANT:  This function is called both at install and update time.  If this
+ * method is modified to add additional fields in the future, the update
+ * strategy must be considered.  See the comment in uuid_update_7102.
  */
  */
 function _uuid_install_uuid_fields() {
 function _uuid_install_uuid_fields() {
   $field = uuid_schema_field_definition();
   $field = uuid_schema_field_definition();
-  foreach (uuid_get_core_entity_info() as $entity_type => $info) {
+  foreach (uuid_get_core_entity_info() as $info) {
     if (!db_field_exists($info['base table'], $info['entity keys']['uuid'])) {
     if (!db_field_exists($info['base table'], $info['entity keys']['uuid'])) {
       db_add_field($info['base table'], $info['entity keys']['uuid'], $field);
       db_add_field($info['base table'], $info['entity keys']['uuid'], $field);
       db_add_index($info['base table'], $info['entity keys']['uuid'], array($info['entity keys']['uuid']));
       db_add_index($info['base table'], $info['entity keys']['uuid'], array($info['entity keys']['uuid']));
@@ -76,7 +91,7 @@ function _uuid_install_uuid_fields() {
  * Implements hook_uninstall().
  * Implements hook_uninstall().
  */
  */
 function uuid_uninstall() {
 function uuid_uninstall() {
-  foreach (uuid_get_core_entity_info() as $entity_type => $info) {
+  foreach (uuid_get_core_entity_info() as $info) {
     if (db_field_exists($info['base table'], $info['entity keys']['uuid'])) {
     if (db_field_exists($info['base table'], $info['entity keys']['uuid'])) {
       db_drop_field($info['base table'], $info['entity keys']['uuid']);
       db_drop_field($info['base table'], $info['entity keys']['uuid']);
       db_drop_index($info['base table'], $info['entity keys']['uuid']);
       db_drop_index($info['base table'], $info['entity keys']['uuid']);
@@ -112,8 +127,7 @@ function uuid_update_6001() {
 }
 }
 
 
 /**
 /**
- * For each of out tables, drop the indexe on the UUID column and add a unique
- * key on that column.
+ * Make all uuid columns unique keys instead of indexes.
  */
  */
 function uuid_update_6002() {
 function uuid_update_6002() {
   $ret = array();
   $ret = array();
@@ -138,8 +152,7 @@ function uuid_update_6003() {
 }
 }
 
 
 /**
 /**
- * Fix the column definitions for uuid columns in all tables
- * to use the more efficient char spec.
+ * Change column definitions for uuid columns to more efficient char spec.
  */
  */
 function uuid_update_6004() {
 function uuid_update_6004() {
   $ret = array();
   $ret = array();
@@ -158,6 +171,8 @@ function uuid_update_6004() {
 }
 }
 
 
 /**
 /**
+ * Support deleting node revision.
+ *
  * Modify existing uuid_node_revisions table to support revision deletion, and
  * Modify existing uuid_node_revisions table to support revision deletion, and
  * add in as much legacy data as possible.
  * add in as much legacy data as possible.
  */
  */
@@ -204,15 +219,17 @@ function uuid_update_7100() {
 }
 }
 
 
 /**
 /**
- * Clear cache for installations that used alpha1. Modules that previously was
- * enabled in uuid_update_7100() doesn't exist anymore.
+ * Clear cache for installations that used alpha1.
+ *
+ * Modules previously enabled in uuid_update_7100() don't exist any more. We
+ * need to clear the cache so Drupal detects this change.
  */
  */
 function uuid_update_7101() {
 function uuid_update_7101() {
   drupal_flush_all_caches();
   drupal_flush_all_caches();
 }
 }
 
 
 /**
 /**
- * Insure that the uuid and vuuid fields are added where needed.
+ * Ensure that the uuid and vuuid fields are added where needed.
  *
  *
  * Note that update 7102 calls _uuid_install_uuid_fields(), which is an
  * Note that update 7102 calls _uuid_install_uuid_fields(), which is an
  * idempotent function.  If _uuid_install_uuid_fields() is changed at some
  * idempotent function.  If _uuid_install_uuid_fields() is changed at some
@@ -220,8 +237,8 @@ function uuid_update_7101() {
  * will have run update 7102, and some will not.  A new uuid_update_7103()
  * will have run update 7102, and some will not.  A new uuid_update_7103()
  * function would would therefore be necessary to update all users to
  * function would would therefore be necessary to update all users to
  * the latest schema.  At the same time, uuid_update_7102() could become
  * the latest schema.  At the same time, uuid_update_7102() could become
- * an empty function, as it would not be necessary to call _uuid_install_uuid_fields()
- * twice.
+ * an empty function, as it would not be necessary to call
+ * _uuid_install_uuid_fields() twice.
  */
  */
 function uuid_update_7102() {
 function uuid_update_7102() {
   // If the user have disabled the UUID module during upgrade (as UPGRADE.txt
   // If the user have disabled the UUID module during upgrade (as UPGRADE.txt
@@ -230,3 +247,47 @@ function uuid_update_7102() {
   _uuid_install_uuid_fields();
   _uuid_install_uuid_fields();
   uuid_sync_all();
   uuid_sync_all();
 }
 }
+
+/**
+ * Clean up entities created by uuid_default_entities_example module.
+ *
+ * Modify the labels of all example entities created by the now removed
+ * uuid_default_entities_example.module to make it clear they're examples. Also
+ * remove the administrator role of any example user.
+ */
+function uuid_update_7103() {
+  // These are UUIDs of all the example entities that might exist after having
+  // installed uuid_default_entities_example.module.
+  $info = entity_get_info();
+  $uuids = array(
+    'node' => array(
+      'b0558664-c94b-3674-d9df-3e1696b2e471',
+      '5e3d8bbe-a1f2-f2d4-fdc0-71e6c23aa837',
+    ),
+    'user' => array(
+      '7cf875e6-dc15-4404-f190-5a7c3e91d14c',
+    ),
+  );
+  // We can't assume taxonomy is enabled.
+  if (isset($info['taxonomy_term'])) {
+    $uuids['taxonomy_term'] = array(
+      'bcb92ce8-2236-e264-65c8-0c163ae716d1',
+      '4293a15c-531a-6164-7d1b-668ed019a6bd',
+      'af738a46-f278-cf84-d94d-9e03879fd71e',
+    );
+  }
+  foreach (array_keys($uuids) as $entity_type) {
+    $info = entity_get_info($entity_type);
+    $entity_ids = entity_get_id_by_uuid($entity_type, $uuids[$entity_type]);
+    $entities = entity_load($entity_type, $entity_ids);
+    foreach ($entities as $entity) {
+      // Update the label to make it clear this is example content.
+      $entity->{$info['entity keys']['label']} = $entity->{$info['entity keys']['label']} . ' (UUID example)';
+      // Remove the administrator role from any user.
+      if ($entity_type == 'user' && $rid = array_search('administrator', $entity->roles)) {
+        unset($entity->roles[$rid]);
+      }
+      entity_save($entity_type, $entity);
+    }
+  }
+}

+ 24 - 21
sites/all/modules/uuid/uuid.module

@@ -25,7 +25,7 @@ module_load_include('inc', 'uuid', 'uuid.entity');
 module_load_include('inc', 'uuid', 'uuid.core');
 module_load_include('inc', 'uuid', 'uuid.core');
 
 
 /**
 /**
- * Implements of hook_menu().
+ * Implements hook_menu().
  */
  */
 function uuid_menu() {
 function uuid_menu() {
   $items = array();
   $items = array();
@@ -34,6 +34,7 @@ function uuid_menu() {
     'title' => 'UUID redirector',
     'title' => 'UUID redirector',
     'description' => 'Redirects requests for UUID URIs to the referenced entity.',
     'description' => 'Redirects requests for UUID URIs to the referenced entity.',
     'page callback' => 'uuid_redirector',
     'page callback' => 'uuid_redirector',
+    // The access check is handled in the page callback.
     'access callback' => TRUE,
     'access callback' => TRUE,
     'type' => MENU_CALLBACK,
     'type' => MENU_CALLBACK,
   );
   );
@@ -44,7 +45,6 @@ function uuid_menu() {
     'page callback' => 'drupal_get_form',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('uuid_admin_form'),
     'page arguments' => array('uuid_admin_form'),
     'access arguments' => array('administer uuid'),
     'access arguments' => array('administer uuid'),
-    'type' => MENU_NORMAL_ITEM,
     'file' => 'uuid.admin.inc',
     'file' => 'uuid.admin.inc',
   );
   );
 
 
@@ -72,7 +72,7 @@ function uuid_menu() {
 }
 }
 
 
 /**
 /**
- * Implements of hook_ctools_plugin_directory().
+ * Implements hook_ctools_plugin_directory().
  */
  */
 function uuid_ctools_plugin_directory($module, $plugin) {
 function uuid_ctools_plugin_directory($module, $plugin) {
   if ($module == 'ctools') {
   if ($module == 'ctools') {
@@ -81,7 +81,7 @@ function uuid_ctools_plugin_directory($module, $plugin) {
 }
 }
 
 
 /**
 /**
- * Implements of hook_permission().
+ * Implements hook_permission().
  */
  */
 function uuid_permission() {
 function uuid_permission() {
   return array(
   return array(
@@ -123,9 +123,8 @@ function uuid_hook_info() {
   return array_fill_keys($hook_names, array('group' => 'uuid'));
   return array_fill_keys($hook_names, array('group' => 'uuid'));
 }
 }
 
 
-
 /**
 /**
- * Implementation of hook_views_api().
+ * Implements hook_views_api().
  */
  */
 function uuid_views_api() {
 function uuid_views_api() {
   return array(
   return array(
@@ -135,27 +134,27 @@ function uuid_views_api() {
 }
 }
 
 
 /**
 /**
- * Implements of hook_module_implements_alter().
+ * Implements hook_module_implements_alter().
  *
  *
- * Moves implementation of hook_entity_info_alter() to the bottom so it is
+ * Moves hook_entity_info_alter() implementation to the bottom so it is
  * invoked after all modules relying on the entity API.
  * invoked after all modules relying on the entity API.
  *
  *
  * @see uuid_entity_info_alter()
  * @see uuid_entity_info_alter()
  */
  */
-function uuid_module_implements_alter(&$Implementss, $hook) {
+function uuid_module_implements_alter(&$implementss, $hook) {
   if ($hook == 'entity_info_alter') {
   if ($hook == 'entity_info_alter') {
     // Move our hook Implements to the bottom.
     // Move our hook Implements to the bottom.
-    $group = $Implementss['uuid'];
-    unset($Implementss['uuid']);
-    $Implementss['uuid'] = $group;
+    $group = $implementss['uuid'];
+    unset($implementss['uuid']);
+    $implementss['uuid'] = $group;
   }
   }
 }
 }
 
 
 /**
 /**
- * Implements of hook_uuid_sync().
+ * Implements hook_uuid_sync().
  */
  */
 function uuid_uuid_sync() {
 function uuid_uuid_sync() {
-  foreach (entity_get_info() as $entity_type => $info) {
+  foreach (entity_get_info() as $info) {
     if (isset($info['uuid']) && $info['uuid'] == TRUE && !empty($info['entity keys']['uuid'])) {
     if (isset($info['uuid']) && $info['uuid'] == TRUE && !empty($info['entity keys']['uuid'])) {
       _uuid_sync_table($info['base table'], $info['entity keys']['id'], $info['entity keys']['uuid']);
       _uuid_sync_table($info['base table'], $info['entity keys']['id'], $info['entity keys']['uuid']);
       if (!empty($info['entity keys']['revision uuid'])) {
       if (!empty($info['entity keys']['revision uuid'])) {
@@ -185,7 +184,7 @@ function _uuid_sync_table($table, $id_field, $uuid_field) {
 }
 }
 
 
 /**
 /**
- * Implementation of hook_features_api().
+ * Implements hook_features_api().
  *
  *
  * The Features support consists of exporting entities from a Deploy
  * The Features support consists of exporting entities from a Deploy
  * <em>fetch-only</em> plan. Deploy is only required to generate the feature
  * <em>fetch-only</em> plan. Deploy is only required to generate the feature
@@ -202,7 +201,7 @@ function uuid_features_api() {
       'default_hook' => 'uuid_default_entities',
       'default_hook' => 'uuid_default_entities',
       'default_file' => FEATURES_DEFAULTS_INCLUDED,
       'default_file' => FEATURES_DEFAULTS_INCLUDED,
       'feature_source' => TRUE,
       'feature_source' => TRUE,
-      'file' => drupal_get_path('module', 'uuid') .'/uuid.features.inc',
+      'file' => drupal_get_path('module', 'uuid') . '/uuid.features.inc',
     ),
     ),
   );
   );
 }
 }
@@ -212,18 +211,22 @@ function uuid_features_api() {
  */
  */
 function uuid_redirector() {
 function uuid_redirector() {
   $entity_data = uuid_uri_array_to_data(arg());
   $entity_data = uuid_uri_array_to_data(arg());
-  
+
   $entity_info = entity_get_info($entity_data['entity_type']);
   $entity_info = entity_get_info($entity_data['entity_type']);
   if (empty($entity_info['uuid'])) {
   if (empty($entity_info['uuid'])) {
-    return drupal_not_found();
+    return MENU_NOT_FOUND;
   }
   }
 
 
   $entities = entity_uuid_load($entity_data['entity_type'], array($entity_data['uuid']));
   $entities = entity_uuid_load($entity_data['entity_type'], array($entity_data['uuid']));
   if (!count($entities)) {
   if (!count($entities)) {
-    return drupal_not_found();
+    return MENU_NOT_FOUND;
   }
   }
 
 
   $uri = entity_uri($entity_data['entity_type'], current($entities));
   $uri = entity_uri($entity_data['entity_type'], current($entities));
-  drupal_goto($uri['path'], array(), 301);
-}
 
 
+  if (!drupal_valid_path($uri['path'])) {
+    return MENU_ACCESS_DENIED;
+  }
+
+  drupal_goto($uri['path'], $uri['options'], 301);
+}

+ 303 - 287
sites/all/modules/uuid/uuid.test

@@ -6,20 +6,28 @@
  */
  */
 
 
 /**
 /**
- * Base class with some helper methods.
+ * UUID test helper trait.
+ *
+ * Contains methods that assist with running UUID tests.
  */
  */
-class UUIDTestCase extends DrupalWebTestCase {
-
-  function setUp() {
-    parent::setUp(func_get_args());
-  }
+trait UUIDTestHelper {
 
 
   /**
   /**
    * Helper function that asserts a UUID.
    * Helper function that asserts a UUID.
    */
    */
-  function assertUUID($uuid, $message = NULL) {
+  protected function assertUuid($uuid, $message = NULL) {
     $this->assertTrue(uuid_is_valid($uuid), $message);
     $this->assertTrue(uuid_is_valid($uuid), $message);
   }
   }
+
+}
+
+/**
+ * Base class with some helper methods.
+ */
+abstract class UUIDTestCase extends DrupalWebTestCase {
+
+  use UUIDTestHelper;
+
 }
 }
 
 
 /**
 /**
@@ -27,6 +35,9 @@ class UUIDTestCase extends DrupalWebTestCase {
  */
  */
 class UUIDAPITestCase extends UUIDTestCase {
 class UUIDAPITestCase extends UUIDTestCase {
 
 
+  /**
+   * {@inheritdoc}
+   */
   public static function getInfo() {
   public static function getInfo() {
     return array(
     return array(
       'name' => 'UUID API',
       'name' => 'UUID API',
@@ -35,26 +46,128 @@ class UUIDAPITestCase extends UUIDTestCase {
     );
     );
   }
   }
 
 
-  function setUp() {
-    parent::setUp('uuid');
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp(array('uuid'));
   }
   }
 
 
-  function testAPIFunctions() {
+  /**
+   * Tests uuid function calls.
+   */
+  public function testApiFunctions() {
     // This is a valid UUID, we know that.
     // This is a valid UUID, we know that.
     $valid_uuid = '0ab26e6b-f074-4e44-9da6-1205fa0e9761';
     $valid_uuid = '0ab26e6b-f074-4e44-9da6-1205fa0e9761';
     // Test the uuid_is_valid() function.
     // Test the uuid_is_valid() function.
-    $this->assertUUID($valid_uuid, 'UUID validation works.');
+    $this->assertUuid($valid_uuid, 'UUID validation works.');
 
 
     // The default generator is 'php'.
     // The default generator is 'php'.
     $uuid = uuid_generate();
     $uuid = uuid_generate();
-    $this->assertUUID($uuid, 'PHP generator works.');
+    $this->assertUuid($uuid, 'PHP generator works.');
 
 
     // Test the 'mysql' generator.
     // Test the 'mysql' generator.
     variable_set('uuid_generator', 'mysql');
     variable_set('uuid_generator', 'mysql');
     drupal_static_reset('uuid_generate');
     drupal_static_reset('uuid_generate');
     $uuid = uuid_generate();
     $uuid = uuid_generate();
-    $this->assertUUID($uuid, 'MySQL generator works.');
+    $this->assertUuid($uuid, 'MySQL generator works.');
   }
   }
+
+  /**
+   * Checks that schema for tables of core entities is correctly defined.
+   */
+  public function testSchemas() {
+    module_load_include('install', 'uuid');
+
+    $schemas = drupal_get_schema();
+    $field_info = uuid_schema_field_definition();
+    $key_names = array(
+      'base table' => 'uuid',
+      'revision table' => 'revision uuid',
+    );
+
+    foreach (uuid_get_core_entity_info() as $entity_info) {
+      // Test the fields in "base" and "revision" tables.
+      foreach ($key_names as $table_type => $key_name) {
+        // Table or field is not defined in entity.
+        if (!isset($entity_info[$table_type], $entity_info['entity keys'][$key_name])) {
+          // Not all entities have a revisions table.
+          continue;
+        }
+
+        $field_name = $entity_info['entity keys'][$key_name];
+        $table_name = $entity_info[$table_type];
+
+        if (!isset($schemas[$table_name])) {
+          $this->fail(sprintf('Database schema does not have a "%s" table.', $table_name));
+          continue;
+        }
+
+        $properties = array(
+          'field' => array('fields', $field_info),
+          'index' => array('indexes', array($field_name)),
+        );
+
+        // Check integrity of the field and index definition.
+        foreach ($properties as $type => $data) {
+          list($property, $value) = $data;
+
+          $message = sprintf('Definition of the "%s" %s in the "%s" schema', $field_name, $type, $table_name);
+
+          if (isset($schemas[$table_name][$property][$field_name])) {
+            $this->assertIdentical($schemas[$table_name][$property][$field_name], $value, "$message is correct.");
+          }
+          else {
+            $this->fail("$message does not exist.");
+          }
+        }
+      }
+    }
+  }
+
+}
+
+/**
+ * Tests the UUID API functions.
+ */
+class UUIDV5TestCase extends UUIDTestCase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'UUID v5',
+      'description' => 'Tests the UUID v5 function.',
+      'group' => 'UUID',
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp(array('uuid'));
+  }
+
+  /**
+   * Tests uuid function calls.
+   */
+  public function testV5Function() {
+    // DNS namespace UUID.
+    $dns_namespace = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
+
+    // Valid DNS generation test.
+    $uuid = uuid_generate_v5($dns_namespace, 'drupal.org');
+    $this->assertUuid($uuid, 'UUID for drupal.org is valid.');
+    $this->assertEqual($uuid, 'c809fd30-48df-52e3-a9f2-2cd78129b8b1', 'UUID for drupal.org is correct.');
+
+    // Invalid namespace test.
+    $invalid_namespace = '01234567-c7a9-feda-27e5-75d00dabc123';
+    $uuid = uuid_generate_v5($invalid_namespace, 'drupal.org');
+    $this->assertFalse($uuid, 'Invalid namespace UUID rejected.');
+  }
+
 }
 }
 
 
 /**
 /**
@@ -62,6 +175,9 @@ class UUIDAPITestCase extends UUIDTestCase {
  */
  */
 class UUIDEntityTestCase extends UUIDTestCase {
 class UUIDEntityTestCase extends UUIDTestCase {
 
 
+  /**
+   * {@inheritdoc}
+   */
   public static function getInfo() {
   public static function getInfo() {
     return array(
     return array(
       'name' => 'Entity API functions',
       'name' => 'Entity API functions',
@@ -70,14 +186,17 @@ class UUIDEntityTestCase extends UUIDTestCase {
     );
     );
   }
   }
 
 
-  function setUp() {
-    parent::setUp('uuid');
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp(array('uuid'));
   }
   }
 
 
   /**
   /**
    * Tests Entity API's UUID functions.
    * Tests Entity API's UUID functions.
    */
    */
-  function testEntityAPIFunctions() {
+  public function testEntityApiFunctions() {
     // Create some entities that we will work with.
     // Create some entities that we will work with.
     $user = $this->drupalCreateUser();
     $user = $this->drupalCreateUser();
     $node = $this->drupalCreateNode(array('title' => 'original title', 'uid' => $user->uid));
     $node = $this->drupalCreateNode(array('title' => 'original title', 'uid' => $user->uid));
@@ -94,6 +213,7 @@ class UUIDEntityTestCase extends UUIDTestCase {
     $vuuids = entity_get_uuid_by_id('node', array($node->vid), TRUE);
     $vuuids = entity_get_uuid_by_id('node', array($node->vid), TRUE);
     $this->assertTrue(in_array($node->vuuid, $vuuids), 'Lookup of entity revision UUID works.');
     $this->assertTrue(in_array($node->vuuid, $vuuids), 'Lookup of entity revision UUID works.');
   }
   }
+
 }
 }
 
 
 /**
 /**
@@ -101,6 +221,9 @@ class UUIDEntityTestCase extends UUIDTestCase {
  */
  */
 class UUIDUserTestCase extends UUIDTestCase {
 class UUIDUserTestCase extends UUIDTestCase {
 
 
+  /**
+   * {@inheritdoc}
+   */
   public static function getInfo() {
   public static function getInfo() {
     return array(
     return array(
       'name' => 'User implementation',
       'name' => 'User implementation',
@@ -109,22 +232,26 @@ class UUIDUserTestCase extends UUIDTestCase {
     );
     );
   }
   }
 
 
-  function setUp() {
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    $modules = array('uuid');
+
     // Some tests depends on the optional Entity API module.
     // Some tests depends on the optional Entity API module.
     if (module_exists('entity')) {
     if (module_exists('entity')) {
-      parent::setUp('uuid', 'entity');
-    }
-    else {
-      parent::setUp('uuid');
+      $modules[] = 'entity';
     }
     }
+
+    parent::setUp($modules);
   }
   }
 
 
   /**
   /**
    * Test CRUD on users with UUID functions.
    * Test CRUD on users with UUID functions.
    */
    */
-  function testUserCRUD() {
+  public function testUserCrud() {
     $user = $this->drupalCreateUser();
     $user = $this->drupalCreateUser();
-    $this->assertUUID($user->uuid, 'User UUID was generated.');
+    $this->assertUuid($user->uuid, 'User UUID was generated.');
 
 
     // Test updating user.
     // Test updating user.
     $user_test = clone $user;
     $user_test = clone $user;
@@ -154,6 +281,7 @@ class UUIDUserTestCase extends UUIDTestCase {
       $this->assertFalse($user_test, 'Deleting user with UUID worked.');
       $this->assertFalse($user_test, 'Deleting user with UUID worked.');
     }
     }
   }
   }
+
 }
 }
 
 
 /**
 /**
@@ -161,6 +289,9 @@ class UUIDUserTestCase extends UUIDTestCase {
  */
  */
 class UUIDNodeTestCase extends UUIDTestCase {
 class UUIDNodeTestCase extends UUIDTestCase {
 
 
+  /**
+   * {@inheritdoc}
+   */
   public static function getInfo() {
   public static function getInfo() {
     return array(
     return array(
       'name' => 'Node implementation',
       'name' => 'Node implementation',
@@ -169,35 +300,46 @@ class UUIDNodeTestCase extends UUIDTestCase {
     );
     );
   }
   }
 
 
-  function setUp() {
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    $modules = array('uuid');
+
     // Some tests depends on the optional Entity API module.
     // Some tests depends on the optional Entity API module.
     if (module_exists('entity')) {
     if (module_exists('entity')) {
-      parent::setUp('uuid', 'entity');
-    }
-    else {
-      parent::setUp('uuid');
+      $modules[] = 'entity';
     }
     }
+
+    parent::setUp($modules);
   }
   }
 
 
   /**
   /**
    * Tests CRUD on nodes with UUID functions.
    * Tests CRUD on nodes with UUID functions.
+   *
+   * @todo
+   *   Break out into multiple test methods to loosen coupling between tests.
    */
    */
-  function testNodeCRUD() {
+  public function testNodeCrud() {
     // Create some entities that we will work with.
     // Create some entities that we will work with.
     $user = $this->drupalCreateUser();
     $user = $this->drupalCreateUser();
     $node = $this->drupalCreateNode(array('title' => 'original title', 'uid' => $user->uid));
     $node = $this->drupalCreateNode(array('title' => 'original title', 'uid' => $user->uid));
 
 
-    $this->assertUUID($node->uuid, 'Node UUID was generated.');
-    $this->assertUUID($node->vuuid, 'Node revision UUID was generated.');
+    $this->assertUuid($node->uuid, 'Node UUID was generated.');
+    $this->assertUuid($node->vuuid, 'Node revision UUID was generated.');
 
 
     // Test node update, without creating new revision.
     // Test node update, without creating new revision.
     $node_test = clone $node;
     $node_test = clone $node;
-    $node_test->title = 'new title';
+    $node_test->title = 'original title';
     $node_test->revision = FALSE;
     $node_test->revision = FALSE;
     node_save($node_test);
     node_save($node_test);
     $node_test = node_load($node->nid, FALSE, TRUE);
     $node_test = node_load($node->nid, FALSE, TRUE);
     $this->assertEqual($node_test->uuid, $node->uuid, 'Node UUID was intact after update, when not creating new revision.');
     $this->assertEqual($node_test->uuid, $node->uuid, 'Node UUID was intact after update, when not creating new revision.');
     $this->assertEqual($node_test->vuuid, $node->vuuid, 'Node revision UUID was intact after updating, when not creating new revision.');
     $this->assertEqual($node_test->vuuid, $node->vuuid, 'Node revision UUID was intact after updating, when not creating new revision.');
+    // Save the original revision IDs that we will test with later.
+    $vid_old = $node_test->vid;
+    $vuuid_old = $node_test->vuuid;
+    $uuid_old = $node_test->uuid;
 
 
     // Test node update, with new revision.
     // Test node update, with new revision.
     $node_test = clone $node;
     $node_test = clone $node;
@@ -207,13 +349,31 @@ class UUIDNodeTestCase extends UUIDTestCase {
     $node_test = node_load($node->nid, FALSE, TRUE);
     $node_test = node_load($node->nid, FALSE, TRUE);
     $this->assertEqual($node_test->uuid, $node->uuid, 'Node UUID was intact after updating, when creating new revision.');
     $this->assertEqual($node_test->uuid, $node->uuid, 'Node UUID was intact after updating, when creating new revision.');
     $this->assertNotEqual($node_test->vuuid, $node->vuuid, 'A new node revision UUID was generated, when creating new revision.');
     $this->assertNotEqual($node_test->vuuid, $node->vuuid, 'A new node revision UUID was generated, when creating new revision.');
-    $this->assertUUID($node_test->vuuid, 'The new node revision UUID was valid.');
+    $this->assertUuid($node_test->vuuid, 'The new node revision UUID was valid.');
 
 
     // Test entity_uuid_load().
     // Test entity_uuid_load().
+    // Save some variables that we will test against.
+    $nid_test = $node_test->nid;
+    $vid_test = $node_test->vid;
+    $uid_test = $user->uuid;
+    $uuid_test = $node_test->uuid;
+    $vuuid_test = $node_test->vuuid;
     $nodes = entity_uuid_load('node', array($node->uuid), array(), TRUE);
     $nodes = entity_uuid_load('node', array($node->uuid), array(), TRUE);
     $node_test = reset($nodes);
     $node_test = reset($nodes);
-    $this->assertEqual($node_test->nid, $node->nid, 'Node was correctly loaded with UUID.');
-    $this->assertEqual($node_test->uid, $user->uuid, "Node property 'uid' was transformed to UUID when loaded with UUID.");
+    $this->assertEqual($node_test->nid, $nid_test, 'Node ID was correct when loading with UUID.');
+    $this->assertEqual($node_test->vid, $vid_test, 'Node revision ID was correct when loading with UUID.');
+    $this->assertEqual($node_test->uid, $uid_test, "Node author ID was transformed to UUID when loaded with UUID.");
+    $this->assertEqual($node_test->uuid, $uuid_test, 'Node UUID was correct when loading with UUID.');
+    $this->assertEqual($node_test->vuuid, $vuuid_test, 'Node revision UUID was correct when loading with UUID.');
+
+    // Test entity_uuid_load() with conditions.
+    // Load the previous revision UUID that we saved earlier.
+    $nodes = entity_uuid_load('node', array($uuid_test), array('vuuid' => $vuuid_old));
+    $node_test = reset($nodes);
+    $this->assertTrue((($node_test->uuid == $uuid_test) && ($node_test->nid && $node->nid)), 'The correct entity was loaded when loading a universal entity with a revision UUID condition.');
+    $this->assertEqual($node_test->vuuid, $vuuid_old, 'Correct revision UUID was loaded when loading a universal entity with a revision UUID condition.');
+    $this->assertEqual($node_test->vid, $vid_old, 'Correct revision ID was loaded when loading a universal entity with a revision UUID condition.');
+    $this->assertEqual($node_test->title, 'original title', 'Correct title was loaded when loading a universal entity with a revision UUID condition.');
 
 
     // The following tests depends on the optional Entity API module.
     // The following tests depends on the optional Entity API module.
     if (module_exists('entity')) {
     if (module_exists('entity')) {
@@ -245,15 +405,79 @@ class UUIDNodeTestCase extends UUIDTestCase {
       $this->assertEqual($node_test->title, 'newer title', 'Saving node with UUID mapped to correct node, when creating new revision.');
       $this->assertEqual($node_test->title, 'newer title', 'Saving node with UUID mapped to correct node, when creating new revision.');
       $this->assertEqual($node_test->uuid, $node->uuid, 'Node UUID was intact after saving with UUID, when creating new revision.');
       $this->assertEqual($node_test->uuid, $node->uuid, 'Node UUID was intact after saving with UUID, when creating new revision.');
       $this->assertNotEqual($node_test->vuuid, $node->vuuid, 'A new node revison UUID was generated after saving with UUID, when creating new revision.');
       $this->assertNotEqual($node_test->vuuid, $node->vuuid, 'A new node revison UUID was generated after saving with UUID, when creating new revision.');
-      $this->assertUUID($node_test->vuuid, 'New node revision UUID was valid.');
+      $this->assertUuid($node_test->vuuid, 'New node revision UUID was valid.');
       $this->assertEqual($node_test->uid, $node->uid, "Node property 'uid' was intact after saving with UUID, when creating new revision.");
       $this->assertEqual($node_test->uid, $node->uid, "Node property 'uid' was intact after saving with UUID, when creating new revision.");
 
 
+      // Test the same thing again, but now triggering a new revision from a
+      // remote environment.
+      // TODO: Move this test to the uuid_services module.
+      $nodes = entity_uuid_load('node', array($node->uuid), array(), TRUE);
+      $node_test = reset($nodes);
+      // Store the current local revision ID to test with later.
+      $vid_old1 = $node_test->vid;
+      // Simulate this node coming from a remote environment by generating
+      // IDs that won't match. Only the UUID match at this point.
+      $node_test->uuid_services = TRUE;
+      $vuuid_test = uuid_generate();
+      $node_test->nid = $nid_test;
+      $node_test->vid = $vid_test;
+      $node_test->vuuid = $vuuid_test;
+      $node_test->revision = TRUE;
+      entity_uuid_save('node', $node_test);
+      $node_test = node_load($node->nid, FALSE, TRUE);
+      $this->assertNotEqual($node_test->vid, $vid_old1, 'A new revision was created, when trying to create new revision with new revision UUID from remote site');
+      $this->assertEqual($node_test->vuuid, $vuuid_test, 'The revison UUID was preserved after saving with UUID, when trying to create new revision with new revision UUID from remote site.');
+
+      // Test the same thing again from a remote environment, but now with the
+      // same vuuid as once previosuly. This should not trigger a new revision.
+      // This covers the case of "dupe deployments" where a client might push a
+      // node several times.
+      // TODO: Move this test to the uuid_services module.
+      $nodes = entity_uuid_load('node', array($node->uuid), array(), TRUE);
+      $node_test = reset($nodes);
+      // Store the current local revision ID to test with later.
+      $vid_old2 = $node_test->vid;
+      // Simulate this node coming from a remote environment by generating
+      // IDs that won't match.
+      $node_test->uuid_services = TRUE;
+      $node_test->nid = $nid_test;
+      $node_test->vid = $vid_test;
+      $node_test->vuuid = $vuuid_test;
+      $node_test->revision = TRUE;
+      entity_uuid_save('node', $node_test);
+      $node_test = node_load($node->nid, FALSE, TRUE);
+      $this->assertEqual($node_test->vid, $vid_old2, 'A new revision was not created, when trying to create new revision with existing revision UUID from remote site.');
+      $this->assertEqual($node_test->vuuid, $vuuid_test, 'The revison UUID was preserved after saving with UUID, when trying to create new revision with existing revision UUID from remote site.');
+
+      // Test the same this again, but now with an old revision.
+      $nodes = entity_uuid_load('node', array($uuid_old), array('vuuid' => $vuuid_old), TRUE);
+      $node_test = reset($nodes);
+      // Simulate this node coming from a remote environment by generating
+      // IDs that won't match.
+      $node_test->uuid_services = TRUE;
+      $node_test->nid = rand();
+      $node_test->vid = rand();
+      $node_test->revision = TRUE;
+      $node_test->title = 'newest title';
+      entity_uuid_save('node', $node_test);
+      $node_test = node_load($node->nid, $vid_old, TRUE);
+      $this->assertEqual($node_test->title, 'newest title', 'The revision was updated, when updating old revision with existing revision UUID from remote site.');
+      $this->assertEqual($node_test->vuuid, $vuuid_old, 'The revison UUID was preserved after saving with UUID, when updating old revision with existing revision UUID from remote site.');
+
+      // Setting the node options variable should also trigger a new revision.
+      $nodes = entity_uuid_load('node', array($node->uuid), array(), TRUE);
+      $node_test = reset($nodes);
+      variable_set('node_options_' . $node_test->type, array('revision'));
+      entity_uuid_save('node', $node_test);
+      $this->assertNotEqual($node_test->vuuid, $node->vuuid, 'A new node revison ID was generated after saving with UUID, when relying on the node options variable.');
+
       // Test entity_uuid_delete() for nodes.
       // Test entity_uuid_delete() for nodes.
       entity_uuid_delete('node', $node->uuid);
       entity_uuid_delete('node', $node->uuid);
       $node_test = node_load($node->nid);
       $node_test = node_load($node->nid);
       $this->assertFalse($node_test, 'Deleting node with UUID worked.');
       $this->assertFalse($node_test, 'Deleting node with UUID worked.');
     }
     }
   }
   }
+
 }
 }
 
 
 /**
 /**
@@ -264,6 +488,11 @@ class UUIDNodeTestCase extends UUIDTestCase {
  */
  */
 class UUIDCommentTestCase extends CommentHelperCase {
 class UUIDCommentTestCase extends CommentHelperCase {
 
 
+  use UUIDTestHelper;
+
+  /**
+   * {@inheritdoc}
+   */
   public static function getInfo() {
   public static function getInfo() {
     return array(
     return array(
       'name' => 'Comment implementation',
       'name' => 'Comment implementation',
@@ -272,31 +501,21 @@ class UUIDCommentTestCase extends CommentHelperCase {
     );
     );
   }
   }
 
 
-  /**
-   * Helper function that asserts a UUID.
-   *
-   * We have duplicated this function from UUIDTestCase since we have to extend
-   * CommentHelperCase instead.
-   */
-  function assertUUID($uuid, $message = NULL) {
-    $this->assertTrue(uuid_is_valid($uuid), $message);
-  }
-
   /**
   /**
    * Test CRUD on comments with UUID functions.
    * Test CRUD on comments with UUID functions.
    */
    */
-  function testCommentCRUD() {
+  public function testCommentCrud() {
     // This is sub optimal, but due to how CommentHelperCase::setUp() is
     // This is sub optimal, but due to how CommentHelperCase::setUp() is
     // constructed we are enforced to do this. So unfortunately this test
     // constructed we are enforced to do this. So unfortunately this test
     // depends on 'entity' module for now.
     // depends on 'entity' module for now.
-    module_enable(array('uuid', 'entity'), TRUE);
+    module_enable(array('uuid', 'entity'));
     $user = $this->drupalCreateUser();
     $user = $this->drupalCreateUser();
     $this->drupalLogin($user);
     $this->drupalLogin($user);
     $node = $this->drupalCreateNode();
     $node = $this->drupalCreateNode();
     $return = $this->postComment($node, 'Lorem ipsum');
     $return = $this->postComment($node, 'Lorem ipsum');
 
 
     $comment = comment_load($return->id);
     $comment = comment_load($return->id);
-    $this->assertUUID($comment->uuid, 'Comment UUID was generated.');
+    $this->assertUuid($comment->uuid, 'Comment UUID was generated.');
 
 
     // Test updating comment.
     // Test updating comment.
     $comment_test = clone $comment;
     $comment_test = clone $comment;
@@ -332,6 +551,7 @@ class UUIDCommentTestCase extends CommentHelperCase {
       $this->assertFalse($comment_test, 'Deleting comment with UUID worked.');
       $this->assertFalse($comment_test, 'Deleting comment with UUID worked.');
     }
     }
   }
   }
+
 }
 }
 
 
 /**
 /**
@@ -339,6 +559,11 @@ class UUIDCommentTestCase extends CommentHelperCase {
  */
  */
 class UUIDTaxonomyTestCase extends TaxonomyWebTestCase {
 class UUIDTaxonomyTestCase extends TaxonomyWebTestCase {
 
 
+  use UUIDTestHelper;
+
+  /**
+   * {@inheritdoc}
+   */
   public static function getInfo() {
   public static function getInfo() {
     return array(
     return array(
       'name' => 'Taxonomy implementation',
       'name' => 'Taxonomy implementation',
@@ -348,40 +573,38 @@ class UUIDTaxonomyTestCase extends TaxonomyWebTestCase {
   }
   }
 
 
   /**
   /**
+   * {@inheritdoc}
+   *
    * A lot of code here is taken from TaxonomyTermTestCase::setUp().
    * A lot of code here is taken from TaxonomyTermTestCase::setUp().
    */
    */
-  function setUp() {
+  protected function setUp() {
+    $modules = array('taxonomy', 'uuid');
+
     // Some tests depends on the optional Entity API module.
     // Some tests depends on the optional Entity API module.
     if (module_exists('entity')) {
     if (module_exists('entity')) {
-      parent::setUp('taxonomy', 'uuid', 'entity');
-    }
-    else {
-      parent::setUp('taxonomy', 'uuid');
+      $modules[] = 'entity';
     }
     }
-  }
 
 
-  /**
-   * Helper function that asserts a UUID.
-   *
-   * We have duplicated this function from UUIDTestCase since we have to extend
-   * TaxonomyWebTestCase instead.
-   */
-  function assertUUID($uuid, $message = NULL) {
-    $this->assertTrue(uuid_is_valid($uuid), $message);
+    parent::setUp($modules);
   }
   }
 
 
   /**
   /**
    * Test CRUD on comments with UUID functions.
    * Test CRUD on comments with UUID functions.
    */
    */
-  function testTaxonomyCRUD() {
-    $user = $this->drupalCreateUser(array('administer taxonomy', 'administer nodes', 'bypass node access'));
+  public function testTaxonomyCrud() {
+    $perms = array(
+      'administer taxonomy',
+      'administer nodes',
+      'bypass node access',
+    );
+    $user = $this->drupalCreateUser($perms);
     $this->drupalLogin($user);
     $this->drupalLogin($user);
 
 
     // Create a term by tagging a node. We'll use this node later too.
     // Create a term by tagging a node. We'll use this node later too.
-    $vocabulary = new stdClass;
+    $vocabulary = new stdClass();
     $vocabulary->vid = 1;
     $vocabulary->vid = 1;
     $term = $this->createTerm($vocabulary);
     $term = $this->createTerm($vocabulary);
-    $this->assertUUID($term->uuid, 'Term UUID was generated.');
+    $this->assertUuid($term->uuid, 'Term UUID was generated.');
 
 
     // Test updating term.
     // Test updating term.
     $term_test = clone $term;
     $term_test = clone $term;
@@ -413,6 +636,7 @@ class UUIDTaxonomyTestCase extends TaxonomyWebTestCase {
       $this->assertFalse($term_test, 'Deleting term with UUID worked.');
       $this->assertFalse($term_test, 'Deleting term with UUID worked.');
     }
     }
   }
   }
+
 }
 }
 
 
 /**
 /**
@@ -420,6 +644,9 @@ class UUIDTaxonomyTestCase extends TaxonomyWebTestCase {
  */
  */
 class UUIDSyncTestCase extends UUIDTestCase {
 class UUIDSyncTestCase extends UUIDTestCase {
 
 
+  /**
+   * {@inheritdoc}
+   */
   public static function getInfo() {
   public static function getInfo() {
     return array(
     return array(
       'name' => 'UUID sync',
       'name' => 'UUID sync',
@@ -434,19 +661,14 @@ class UUIDSyncTestCase extends UUIDTestCase {
    * @todo
    * @todo
    *   There are something weird around this assertion.
    *   There are something weird around this assertion.
    */
    */
-  function assertTableColumn($table, $column, $message) {
-    $result = db_query("SHOW COLUMNS FROM {$table}");
-    $exists = FALSE;
-    foreach ($result as $record) {
-      if ($record->field == $column) {
-        $exists = TRUE;
-        break;
-      }
-    }
-    $this->assertTrue($exists, $message);
+  protected function assertTableColumn($table, $column, $message) {
+    $this->assertTrue(db_field_exists($table, $column), $message);
   }
   }
 
 
-  function testSync() {
+  /**
+   * Tests creating UUIDs for entities that don't have them.
+   */
+  public function testSync() {
     // These entities will not have UUID from the start, since the UUID module
     // These entities will not have UUID from the start, since the UUID module
     // isn't installed yet.
     // isn't installed yet.
     $user = $this->drupalCreateUser();
     $user = $this->drupalCreateUser();
@@ -473,218 +695,12 @@ class UUIDSyncTestCase extends UUIDTestCase {
 
 
     // Test if UUID was generated for nodes.
     // Test if UUID was generated for nodes.
     $node_test = node_load($node->nid, FALSE, TRUE);
     $node_test = node_load($node->nid, FALSE, TRUE);
-    $this->assertUUID($node_test->uuid, 'Node UUID was generated when clicking the sync button.');
-    $this->assertUUID($node_test->vuuid, 'Node revision UUID was generated when clicking the sync button.');
+    $this->assertUuid($node_test->uuid, 'Node UUID was generated when clicking the sync button.');
+    $this->assertUuid($node_test->vuuid, 'Node revision UUID was generated when clicking the sync button.');
 
 
     // Test if UUID was generated for users.
     // Test if UUID was generated for users.
     $user_test = user_load($user->uid, TRUE);
     $user_test = user_load($user->uid, TRUE);
-    $this->assertUUID($user_test->uuid, 'User UUID was generated when clicking the sync button.');
+    $this->assertUuid($user_test->uuid, 'User UUID was generated when clicking the sync button.');
   }
   }
-}
-
-class UUIDExportEntitiesWithDeploy extends DrupalWebTestCase {
 
 
-  public static function getInfo() {
-    return array(
-      'name' => 'Export UUID entities',
-      'description' => 'Test exporting UUID entities with Deploy and Features.',
-      'group' => 'UUID',
-    );
-  }
-
-  function setUp() {
-    parent::setUp('taxonomy', 'uuid', 'entity', 'features', 'deploy', 'deploy_example');
-  }
-
-  function testExport() {
-    $test_user = $this->drupalCreateUser();
-    $test_node = $this->drupalCreateNode(array(
-      'uid' => $test_user->uid,
-    ));
-    deploy_manager_add_to_plan('deploy_example_plan', 'node', $test_node);
-    // TODO: Test the actual insert.
-    $this->assertTrue(TRUE, 'Added a node with a user dependency to be exported as a Feature module.');
-
-    // Login and recreate the example feature. The feature isn't installed. But
-    // Features can still export the code, and we can test it.
-    $web_user = $this->drupalCreateUser(array('administer features'));
-    $this->drupalLogin($web_user);
-    $code = $this->drupalPost('admin/structure/features/uuid_default_entities_example/recreate', array(), t('Download feature'));
-    $this->assertTrue($code, 'Feature module was exported.');
-
-    // Ensure that we find what we expect in the exported code.
-    $node_test1 = preg_match('/' . $test_node->title . '/', $code);
-    $node_test2 = preg_match("/'uri' => 'node\/" . $test_node->uuid . "'/", $code);
-    $this->assertTrue($node_test1, 'Node title was found in the expoted code.');
-    $this->assertTrue($node_test2, 'Node URI was found in the expoted code.');
-    $user_test1 = preg_match('/' . $test_user->name . '/', $code);
-    $user_test2 = preg_match("/'uri' => 'user\/" . $test_user->uuid . "'/", $code);
-    $this->assertTrue($user_test1, 'User was found in the expoted code.');
-    $this->assertTrue($user_test2, 'User URI was found in the expoted code.');
-  }
-}
-
-/**
- * Tests for the UUID synchronization.
- */
-class UUIDImportEntitiesTestCase extends UUIDTestCase {
-
-  /**
-   * Representation of the UUIDs that is exported in our example feature, that
-   * we use for testing.
-   */
-  public $term1_uuid = 'bcb92ce8-2236-e264-65c8-0c163ae716d1';
-  public $term2_uuid = '4293a15c-531a-6164-7d1b-668ed019a6bd';
-  public $term3_uuid = 'af738a46-f278-cf84-d94d-9e03879fd71e';
-  public $node1_uuid = 'b0558664-c94b-3674-d9df-3e1696b2e471';
-  public $node2_uuid = '5e3d8bbe-a1f2-f2d4-fdc0-71e6c23aa837';
-  public $user1_uuid = '7cf875e6-dc15-4404-f190-5a7c3e91d14c';
-
-  /**
-   * Helper method to assert the uuid_entities component in any features.
-   */
-  function assertFeatureState($feature, $state, $message = '') {
-    if (empty($message)) {
-      switch ($state) {
-        case FEATURES_DEFAULT:
-          $readable_state = 'default';
-          break;
-        case FEATURES_OVERRIDDEN:
-          $readable_state = 'overridden';
-          break;
-        default:
-          $readable_state = 'unknown';
-          break;
-      }
-      $message = format_string('%component in %feature had state: %state', array('%component' => 'uuid_entities', '%feature' => $feature, '%state' => $readable_state));
-    }
-    // Ensure that the features we used is in default state.
-    $states = features_get_component_states(array($feature), TRUE, TRUE);
-    if (!$this->assertEqual($states[$feature]['uuid_entities'], $state, $message)) {
-      debug(format_string('Enabling functionality to show diff output for debug purposes.'));
-      $success = module_enable(array('diff'));
-      if ($success) {
-        // Make sure we run on cold caches.
-        drupal_flush_all_caches();
-        drupal_static_reset();
-
-        $user = $this->drupalCreateUser(array('administer features'));
-        $this->drupalLogin($user);
-        $this->drupalGet('admin/structure/features/' . $feature . '/diff');
-      }
-      else {
-        debug(format_string('Download !module to see diff output for debug purposes.', array('!module' => 'diff.module')));
-      }
-    }
-  }
-
-  function getEntityByUuid($entity_type, $uuid) {
-    $ids = entity_get_id_by_uuid($entity_type, array($uuid));
-    $entities = entity_load($entity_type, $ids, NULL, TRUE);
-    return reset($entities);
-  }
-
-  function enableFeature($feature) {
-    $success = module_enable(array($feature), TRUE);
-    $this->assertTrue($success, t('Enabled modules: %modules', array('%modules' => implode(', ', array($feature)))));
-    // Make sure we run on cold caches.
-    drupal_flush_all_caches();
-    drupal_static_reset();
-  }
-
-  function revertFeature($feature) {
-    features_revert(array($feature => array('uuid_entities')));
-    $this->assertTrue(TRUE, format_string('Reverted feature: %feature', array('%feature' => $feature)));
-  }
-
-  function testImport() {
-    $term1 = $this->getEntityByUuid('taxonomy_term', $this->term1_uuid);
-    $term2 = $this->getEntityByUuid('taxonomy_term', $this->term2_uuid);
-    $term3 = $this->getEntityByUuid('taxonomy_term', $this->term3_uuid);
-    $node1 = $this->getEntityByUuid('node', $this->node1_uuid);
-    $node2 = $this->getEntityByUuid('node', $this->node2_uuid);
-    $user1 = $this->getEntityByUuid('user', $this->user1_uuid);
-
-    // Ensure that we don't have our entities yet.
-    $this->assertTrue(empty($term1), 'Term 1 has not been created yet.');
-    $this->assertTrue(empty($term2), 'Term 2 has not been created yet.');
-    $this->assertTrue(empty($term3), 'Term 3 has not been created yet.');
-    $this->assertTrue(empty($node1), 'Node 1 has not been created yet.');
-    $this->assertTrue(empty($node2), 'Node 2 has not been created yet.');
-    $this->assertTrue(empty($user1), 'User 1 has not been created yet.');
-
-    $this->enableFeature('uuid_default_entities_example');
-
-    $term1 = $this->getEntityByUuid('taxonomy_term', $this->term1_uuid);
-    $term2 = $this->getEntityByUuid('taxonomy_term', $this->term2_uuid);
-    $term3 = $this->getEntityByUuid('taxonomy_term', $this->term3_uuid);
-    $node1 = $this->getEntityByUuid('node', $this->node1_uuid);
-    $node2 = $this->getEntityByUuid('node', $this->node2_uuid);
-    $user1 = $this->getEntityByUuid('user', $this->user1_uuid);
-
-    // Ensure that our entities was created.
-    $this->assertEqual($term1->uuid, $this->term1_uuid, 'Term 1 was created.');
-    $this->assertEqual($term2->uuid, $this->term2_uuid, 'Term 2 was created.');
-    $this->assertEqual($term3->uuid, $this->term3_uuid, 'Term 3 was created.');
-    $this->assertEqual($node1->uuid, $this->node1_uuid, 'Node 1 was created.');
-    $this->assertEqual($node2->uuid, $this->node2_uuid, 'Node 2 was created.');
-    $this->assertEqual($user1->uuid, $this->user1_uuid, 'User 1 was created.');
-
-    // Check the features state.
-    $this->assertFeatureState('uuid_default_entities_example', FEATURES_DEFAULT);
-
-    // New property.
-    $new = 'foo bar';
-    // Change a term.
-    $term1->name = $new;
-    $status = taxonomy_term_save($term1);
-    $this->assertEqual($status, SAVED_UPDATED, 'Updated term 1.');
-    // Change a node.
-    $node1->title = $new;
-    node_save($node1);
-    $this->assertEqual($node1->title, $new, 'Updated node 1.');
-    // Change a user.
-    $user1->name = $new;
-    $updated_user = user_save($user1);
-    $this->assertEqual($user1->name, $updated_user->name, 'Updated user 1.');
-
-    // Check the features state.
-    $this->assertFeatureState('uuid_default_entities_example', FEATURES_OVERRIDDEN);
-
-    // Revert the feature.
-    $this->revertFeature('uuid_default_entities_example');
-
-    // Check the features state.
-    $this->assertFeatureState('uuid_default_entities_example', FEATURES_DEFAULT);
-  }
-}
-
-class UUIDImportEntitiesWithDeploy extends UUIDImportEntitiesTestCase {
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Import UUID entities, with Deploy',
-      'description' => 'Test importing UUID entities with Features and Deploy.',
-      'group' => 'UUID',
-    );
-  }
-
-  function setUp() {
-    parent::setUp('taxonomy', 'uuid', 'entity', 'features', 'deploy', 'deploy_example');
-  }
-}
-
-class UUIDImportEntitiesWithoutDeploy extends UUIDImportEntitiesTestCase {
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Import UUID entities, without Deploy',
-      'description' => 'Test importing UUID entities with Features only.',
-      'group' => 'UUID',
-    );
-  }
-
-  function setUp() {
-    parent::setUp('taxonomy', 'uuid', 'entity', 'features');
-  }
 }
 }

+ 14 - 0
sites/all/modules/uuid/uuid.tokens.inc

@@ -28,6 +28,20 @@ function uuid_token_info() {
   return $tokens;
   return $tokens;
 }
 }
 
 
+/**
+ * Implements hook_token_info_alter().
+ */
+function uuid_token_info_alter(&$data) {
+  foreach (entity_get_info() as $entity_type => $info) {
+    if (isset($info['uuid']) && $info['uuid'] == TRUE && !empty($info['entity keys']['uuid'])) {
+      $token_type = !empty($info['token type']) ? $info['token type'] : $entity_type;
+      if (empty($data['types'][$token_type])) {
+        unset($data['tokens'][$token_type]);
+      }
+    }
+  }
+}
+
 /**
 /**
  * Implements hook_tokens().
  * Implements hook_tokens().
  */
  */

+ 2 - 1
sites/all/modules/uuid/uuid.views.inc

@@ -1,7 +1,8 @@
 <?php
 <?php
+
 /**
 /**
  * @file
  * @file
- * Views Implementation for UUID
+ * Views Implementation for UUID.
  */
  */
 
 
 /**
 /**

+ 0 - 402
sites/all/modules/uuid/uuid_default_entities_example/uuid_default_entities_example.features.uuid_entities.inc

@@ -1,402 +0,0 @@
-<?php
-/**
- * @file
- * uuid_default_entities_example.features.uuid_entities.inc
- */
-
-/**
- * Implements hook_uuid_default_entities().
- */
-function uuid_default_entities_example_uuid_default_entities() {
-  $entities = array();
-
-  $entities['deploy_example_plan'][] = (object) array(
-    '__metadata' => array(
-      'type' => 'taxonomy_term',
-      'uri' => 'taxonomy_term/bcb92ce8-2236-e264-65c8-0c163ae716d1',
-      'cause' => 'node/b0558664-c94b-3674-d9df-3e1696b2e471',
-    ),
-    'description' => NULL,
-    'format' => NULL,
-    'name' => 'Foo',
-    'path' => array(
-      'alias' => 'term/foo',
-    ),
-    'rdf_mapping' => array(
-      'rdftype' => array(
-        0 => 'skos:Concept',
-      ),
-      'name' => array(
-        'predicates' => array(
-          0 => 'rdfs:label',
-          1 => 'skos:prefLabel',
-        ),
-      ),
-      'description' => array(
-        'predicates' => array(
-          0 => 'skos:definition',
-        ),
-      ),
-      'vid' => array(
-        'predicates' => array(
-          0 => 'skos:inScheme',
-        ),
-        'type' => 'rel',
-      ),
-      'parent' => array(
-        'predicates' => array(
-          0 => 'skos:broader',
-        ),
-        'type' => 'rel',
-      ),
-    ),
-    'uuid' => 'bcb92ce8-2236-e264-65c8-0c163ae716d1',
-    'vocabulary_machine_name' => 'tags',
-    'weight' => '0',
-  );
-  $entities['deploy_example_plan'][] = (object) array(
-    '__metadata' => array(
-      'type' => 'taxonomy_term',
-      'uri' => 'taxonomy_term/4293a15c-531a-6164-7d1b-668ed019a6bd',
-      'cause' => 'node/b0558664-c94b-3674-d9df-3e1696b2e471',
-    ),
-    'description' => NULL,
-    'format' => NULL,
-    'name' => 'Bar',
-    'rdf_mapping' => array(
-      'rdftype' => array(
-        0 => 'skos:Concept',
-      ),
-      'name' => array(
-        'predicates' => array(
-          0 => 'rdfs:label',
-          1 => 'skos:prefLabel',
-        ),
-      ),
-      'description' => array(
-        'predicates' => array(
-          0 => 'skos:definition',
-        ),
-      ),
-      'vid' => array(
-        'predicates' => array(
-          0 => 'skos:inScheme',
-        ),
-        'type' => 'rel',
-      ),
-      'parent' => array(
-        'predicates' => array(
-          0 => 'skos:broader',
-        ),
-        'type' => 'rel',
-      ),
-    ),
-    'uuid' => '4293a15c-531a-6164-7d1b-668ed019a6bd',
-    'vocabulary_machine_name' => 'tags',
-    'weight' => '0',
-  );
-  $entities['deploy_example_plan'][] = (object) array(
-    '__metadata' => array(
-      'type' => 'node',
-      'uri' => 'node/b0558664-c94b-3674-d9df-3e1696b2e471',
-      'cause' => FALSE,
-    ),
-    'body' => array(
-      'und' => array(
-        0 => array(
-          'format' => 'filtered_html',
-          'summary' => '',
-          'value' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
-        ),
-      ),
-    ),
-    'cid' => '0',
-    'comment' => '2',
-    'comment_count' => '0',
-    'field_image' => array(),
-    'field_tags' => array(
-      'und' => array(
-        0 => array(
-          'tid' => 'bcb92ce8-2236-e264-65c8-0c163ae716d1',
-        ),
-        1 => array(
-          'tid' => '4293a15c-531a-6164-7d1b-668ed019a6bd',
-        ),
-      ),
-    ),
-    'language' => 'und',
-    'last_comment_name' => NULL,
-    'last_comment_uid' => '1',
-    'log' => '',
-    'path' => array(
-      'alias' => 'lorem-ipsum',
-    ),
-    'promote' => '1',
-    'rdf_mapping' => array(
-      'field_image' => array(
-        'predicates' => array(
-          0 => 'og:image',
-          1 => 'rdfs:seeAlso',
-        ),
-        'type' => 'rel',
-      ),
-      'field_tags' => array(
-        'predicates' => array(
-          0 => 'dc:subject',
-        ),
-        'type' => 'rel',
-      ),
-      'rdftype' => array(
-        0 => 'sioc:Item',
-        1 => 'foaf:Document',
-      ),
-      'title' => array(
-        'predicates' => array(
-          0 => 'dc:title',
-        ),
-      ),
-      'created' => array(
-        'predicates' => array(
-          0 => 'dc:date',
-          1 => 'dc:created',
-        ),
-        'datatype' => 'xsd:dateTime',
-        'callback' => 'date_iso8601',
-      ),
-      'changed' => array(
-        'predicates' => array(
-          0 => 'dc:modified',
-        ),
-        'datatype' => 'xsd:dateTime',
-        'callback' => 'date_iso8601',
-      ),
-      'body' => array(
-        'predicates' => array(
-          0 => 'content:encoded',
-        ),
-      ),
-      'uid' => array(
-        'predicates' => array(
-          0 => 'sioc:has_creator',
-        ),
-        'type' => 'rel',
-      ),
-      'name' => array(
-        'predicates' => array(
-          0 => 'foaf:name',
-        ),
-      ),
-      'comment_count' => array(
-        'predicates' => array(
-          0 => 'sioc:num_replies',
-        ),
-        'datatype' => 'xsd:integer',
-      ),
-      'last_activity' => array(
-        'predicates' => array(
-          0 => 'sioc:last_activity_date',
-        ),
-        'datatype' => 'xsd:dateTime',
-        'callback' => 'date_iso8601',
-      ),
-    ),
-    'status' => '1',
-    'sticky' => '0',
-    'title' => 'Lorem ipsum',
-    'tnid' => '0',
-    'translate' => '0',
-    'type' => 'article',
-    'uid' => '1',
-    'uuid' => 'b0558664-c94b-3674-d9df-3e1696b2e471',
-  );
-  $entities['deploy_example_plan'][] = (object) array(
-    '__metadata' => array(
-      'type' => 'taxonomy_term',
-      'uri' => 'taxonomy_term/af738a46-f278-cf84-d94d-9e03879fd71e',
-      'cause' => 'node/5e3d8bbe-a1f2-f2d4-fdc0-71e6c23aa837',
-    ),
-    'description' => NULL,
-    'format' => NULL,
-    'name' => 'Baz',
-    'rdf_mapping' => array(
-      'rdftype' => array(
-        0 => 'skos:Concept',
-      ),
-      'name' => array(
-        'predicates' => array(
-          0 => 'rdfs:label',
-          1 => 'skos:prefLabel',
-        ),
-      ),
-      'description' => array(
-        'predicates' => array(
-          0 => 'skos:definition',
-        ),
-      ),
-      'vid' => array(
-        'predicates' => array(
-          0 => 'skos:inScheme',
-        ),
-        'type' => 'rel',
-      ),
-      'parent' => array(
-        'predicates' => array(
-          0 => 'skos:broader',
-        ),
-        'type' => 'rel',
-      ),
-    ),
-    'uuid' => 'af738a46-f278-cf84-d94d-9e03879fd71e',
-    'vocabulary_machine_name' => 'tags',
-    'weight' => '0',
-  );
-  $entities['deploy_example_plan'][] = (object) array(
-    '__metadata' => array(
-      'type' => 'user',
-      'uri' => 'user/7cf875e6-dc15-4404-f190-5a7c3e91d14c',
-      'cause' => 'node/5e3d8bbe-a1f2-f2d4-fdc0-71e6c23aa837',
-    ),
-    'init' => 'no@example.com',
-    'language' => '',
-    'mail' => 'no@example.com',
-    'name' => 'mohamed',
-    'pass' => '$S$DtyVr4YQkvCpofZdLT4.L23Xb6E8HUkmEgZikN919RTZXZSePwso',
-    'picture' => NULL,
-    'rdf_mapping' => array(
-      'rdftype' => array(
-        0 => 'sioc:UserAccount',
-      ),
-      'name' => array(
-        'predicates' => array(
-          0 => 'foaf:name',
-        ),
-      ),
-      'homepage' => array(
-        'predicates' => array(
-          0 => 'foaf:page',
-        ),
-        'type' => 'rel',
-      ),
-    ),
-    'roles' => array(
-      2 => 'authenticated user',
-      3 => 'administrator',
-    ),
-    'signature' => '',
-    'signature_format' => 'filtered_html',
-    'status' => '1',
-    'theme' => '',
-    'timezone' => 'Asia/Riyadh',
-    'uuid' => '7cf875e6-dc15-4404-f190-5a7c3e91d14c',
-  );
-  $entities['deploy_example_plan'][] = (object) array(
-    '__metadata' => array(
-      'type' => 'node',
-      'uri' => 'node/5e3d8bbe-a1f2-f2d4-fdc0-71e6c23aa837',
-      'cause' => FALSE,
-    ),
-    'body' => array(
-      'und' => array(
-        0 => array(
-          'format' => 'filtered_html',
-          'summary' => '',
-          'value' => 'Nunc sollicitudin justo ut augue egestas et varius quam consectetur.',
-        ),
-      ),
-    ),
-    'cid' => '0',
-    'comment' => '2',
-    'comment_count' => '0',
-    'field_image' => array(),
-    'field_tags' => array(
-      'und' => array(
-        0 => array(
-          'tid' => 'af738a46-f278-cf84-d94d-9e03879fd71e',
-        ),
-      ),
-    ),
-    'language' => 'und',
-    'last_comment_name' => NULL,
-    'last_comment_uid' => '7cf875e6-dc15-4404-f190-5a7c3e91d14c',
-    'log' => '',
-    'promote' => '1',
-    'rdf_mapping' => array(
-      'field_image' => array(
-        'predicates' => array(
-          0 => 'og:image',
-          1 => 'rdfs:seeAlso',
-        ),
-        'type' => 'rel',
-      ),
-      'field_tags' => array(
-        'predicates' => array(
-          0 => 'dc:subject',
-        ),
-        'type' => 'rel',
-      ),
-      'rdftype' => array(
-        0 => 'sioc:Item',
-        1 => 'foaf:Document',
-      ),
-      'title' => array(
-        'predicates' => array(
-          0 => 'dc:title',
-        ),
-      ),
-      'created' => array(
-        'predicates' => array(
-          0 => 'dc:date',
-          1 => 'dc:created',
-        ),
-        'datatype' => 'xsd:dateTime',
-        'callback' => 'date_iso8601',
-      ),
-      'changed' => array(
-        'predicates' => array(
-          0 => 'dc:modified',
-        ),
-        'datatype' => 'xsd:dateTime',
-        'callback' => 'date_iso8601',
-      ),
-      'body' => array(
-        'predicates' => array(
-          0 => 'content:encoded',
-        ),
-      ),
-      'uid' => array(
-        'predicates' => array(
-          0 => 'sioc:has_creator',
-        ),
-        'type' => 'rel',
-      ),
-      'name' => array(
-        'predicates' => array(
-          0 => 'foaf:name',
-        ),
-      ),
-      'comment_count' => array(
-        'predicates' => array(
-          0 => 'sioc:num_replies',
-        ),
-        'datatype' => 'xsd:integer',
-      ),
-      'last_activity' => array(
-        'predicates' => array(
-          0 => 'sioc:last_activity_date',
-        ),
-        'datatype' => 'xsd:dateTime',
-        'callback' => 'date_iso8601',
-      ),
-    ),
-    'status' => '1',
-    'sticky' => '0',
-    'title' => 'Nunc sollicitudin',
-    'tnid' => '0',
-    'translate' => '0',
-    'type' => 'article',
-    'uid' => '7cf875e6-dc15-4404-f190-5a7c3e91d14c',
-    'uuid' => '5e3d8bbe-a1f2-f2d4-fdc0-71e6c23aa837',
-  );
-
-  return $entities;
-}

+ 0 - 15
sites/all/modules/uuid/uuid_default_entities_example/uuid_default_entities_example.info

@@ -1,15 +0,0 @@
-core = "7.x"
-dependencies[] = "entity"
-dependencies[] = "features"
-dependencies[] = "uuid"
-description = "Example feature mainly used for testing."
-features[uuid_entities][] = "deploy_example_plan"
-name = "UUID default entities example"
-package = "Features"
-
-; Information added by drupal.org packaging script on 2013-02-03
-version = "7.x-1.0-alpha3+52-dev"
-core = "7.x"
-project = "uuid"
-datestamp = "1359858369"
-

+ 0 - 6
sites/all/modules/uuid/uuid_default_entities_example/uuid_default_entities_example.module

@@ -1,6 +0,0 @@
-<?php
-/**
- * @file
- */
-
-// Drupal needs this blank file.

+ 3 - 4
sites/all/modules/uuid/uuid_path/uuid_path.info

@@ -5,9 +5,8 @@ package = UUID
 dependencies[] = uuid
 dependencies[] = uuid
 
 
 
 
-; Information added by drupal.org packaging script on 2013-02-03
-version = "7.x-1.0-alpha3+52-dev"
+; Information added by Drupal.org packaging script on 2018-07-19
+version = "7.x-1.2"
 core = "7.x"
 core = "7.x"
 project = "uuid"
 project = "uuid"
-datestamp = "1359858369"
-
+datestamp = "1531990689"

+ 7 - 8
sites/all/modules/uuid/uuid_path/uuid_path.module

@@ -2,7 +2,7 @@
 
 
 /**
 /**
  * @file
  * @file
- *   UUID path module functions.
+ * UUID path module functions.
  */
  */
 
 
 /**
 /**
@@ -24,7 +24,7 @@ function uuid_path_entity_uuid_save(&$entity, $entity_type) {
  */
  */
 function _uuid_path_load_url_aliases(&$entities, $entity_type) {
 function _uuid_path_load_url_aliases(&$entities, $entity_type) {
   $info = entity_get_info($entity_type);
   $info = entity_get_info($entity_type);
-  // we only care about entities with URLs.
+  // We only care about entities with URLs.
   if (!isset($info['uri callback'])) {
   if (!isset($info['uri callback'])) {
     return;
     return;
   }
   }
@@ -35,7 +35,7 @@ function _uuid_path_load_url_aliases(&$entities, $entity_type) {
     $aliases = _uuid_path_url_alias_load($path['path']);
     $aliases = _uuid_path_url_alias_load($path['path']);
 
 
     // Ignore local IDs.
     // Ignore local IDs.
-    foreach($aliases as &$alias) {
+    foreach ($aliases as &$alias) {
       unset($alias->pid);
       unset($alias->pid);
       unset($alias->source);
       unset($alias->source);
     }
     }
@@ -50,7 +50,7 @@ function _uuid_path_load_url_aliases(&$entities, $entity_type) {
 function _uuid_path_save_url_aliases(&$entity, $entity_type) {
 function _uuid_path_save_url_aliases(&$entity, $entity_type) {
   $info = entity_get_info($entity_type);
   $info = entity_get_info($entity_type);
 
 
-  // We only care when there is a url callback
+  // We only care when there is a url callback.
   if (!isset($info['uri callback'])) {
   if (!isset($info['uri callback'])) {
     return FALSE;
     return FALSE;
   }
   }
@@ -63,7 +63,7 @@ function _uuid_path_save_url_aliases(&$entity, $entity_type) {
   path_delete(array('source' => $path));
   path_delete(array('source' => $path));
 
 
   // Continue if aliases are present.
   // Continue if aliases are present.
-  if(empty($entity->url_alias)) {
+  if (empty($entity->url_alias)) {
     return FALSE;
     return FALSE;
   }
   }
 
 
@@ -77,10 +77,10 @@ function _uuid_path_save_url_aliases(&$entity, $entity_type) {
 /**
 /**
  * Loads all aliases associated with a path.
  * Loads all aliases associated with a path.
  *
  *
- * @param $path
+ * @param string $path
  *   The source path to look up.
  *   The source path to look up.
  *
  *
- * @return
+ * @return array
  *   Array of paths or NULL if none found.
  *   Array of paths or NULL if none found.
  */
  */
 function _uuid_path_url_alias_load($path) {
 function _uuid_path_url_alias_load($path) {
@@ -90,4 +90,3 @@ function _uuid_path_url_alias_load($path) {
     ->execute()
     ->execute()
     ->fetchAll(PDO::FETCH_OBJ);
     ->fetchAll(PDO::FETCH_OBJ);
 }
 }
-

+ 0 - 12
sites/all/modules/uuid/uuid_services/resources/field_collection.resource.inc

@@ -1,12 +0,0 @@
-<?php
-
-function _field_collection_resource_definition() {
-  if (module_exists('field_collection')) {
-    // We will allow uuid_services_services_resources_alter() to add the
-    // default UUID-related operations to this resource.
-    return array('field_collection_item' => array());
-  }
-  else {
-    return array();
-  }
-}

+ 30 - 0
sites/all/modules/uuid/uuid_services/uuid_services.admin.inc

@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * @file
+ * Administration functions for UUID Service module.
+ */
+
+/**
+ * Settings form for UUID Services.
+ *
+ * @return array
+ *   Configuration form structure.
+ */
+function uuid_services_settings() {
+  $form['uuid_services_support_all_entity_types'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Support all UUID entity types'),
+    '#description' => t('Check this box to automatically provide Services integration for all entity types with UUID support.'),
+    '#default_value' => variable_get('uuid_services_support_all_entity_types', FALSE),
+  );
+  $form['uuid_services_allowed_media_mimes'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Allowed Media Mime type'),
+    '#default_value' => variable_get('uuid_services_allowed_media_mimes', UUID_SERVICES_DEFAULT_ALLOWED_MEDIA_MIMES),
+    '#cols' => 40,
+    '#rows' => 5,
+    '#description' => t("Enter one mime type per line you wish to allow in the system without extension. Example mime type '<em>video/brightcove</em>'."),
+  );
+  return system_settings_form($form);
+}

+ 150 - 0
sites/all/modules/uuid/uuid_services/uuid_services.file_services.test

@@ -0,0 +1,150 @@
+<?php
+
+/**
+ * @file
+ * Test the UUID File Services integration.
+ */
+
+ /**
+  * Test the UUID File Services integration.
+  */
+class UuidFileServicesTest extends ServicesWebTestCase {
+
+  protected $priviledgedUser = NULL;
+
+  protected $endpoint = NULL;
+
+  /**
+   * Implementation of getInfo().
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'UUID File Services tests',
+      'description' => 'Test the file services resource UUID methods and actions.',
+      'group' => 'UUID',
+    );
+  }
+
+  /**
+   * Implementation of setUp().
+   */
+  public function setUp() {
+    parent::setUp(
+      'ctools',
+      'services',
+      'rest_server',
+      'uuid_services',
+      'entity',
+      'file',
+      'field',
+      'file_entity'
+    );
+    $this->endpoint = $this->saveNewEndpoint();
+
+    variable_set('file_entity_default_allowed_extensions', 'jpg jpeg gif png txt doc docx xls xlsx pdf ppt pptx pps ppsx odt ods odp mp3 mov mp4 m4a m4v mpeg avi ogg oga ogv weba webp webm');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function saveNewEndpoint() {
+    $edit = $this->populateEndpointFAPI();
+    $endpoint = new stdClass();
+    $endpoint->disabled = FALSE;
+    $endpoint->api_version = 3;
+    $endpoint->name = $edit['name'];
+    $endpoint->server = $edit['server'];
+    $endpoint->path = $edit['path'];
+    $endpoint->authentication = array(
+      'services' => 'services',
+    );
+    $endpoint->server_settings = array(
+      'formatters' => array(
+        'json' => TRUE,
+        'bencode' => TRUE,
+        'rss' => TRUE,
+        'plist' => TRUE,
+        'xmlplist' => TRUE,
+        'php' => TRUE,
+        'yaml' => TRUE,
+        'jsonp' => FALSE,
+        'xml' => FALSE,
+      ),
+      'parsers' => array(
+        'application/x-yaml' => TRUE,
+        'application/json' => TRUE,
+        'application/vnd.php.serialized' => TRUE,
+        'application/plist' => TRUE,
+        'application/plist+xml' => TRUE,
+        'application/x-www-form-urlencoded' => TRUE,
+        'multipart/form-data' => TRUE,
+      ),
+    );
+    $endpoint->resources = array(
+      'file' => array(
+        'operations' => array(
+          'retrieve' => array(
+            'enabled' => '1',
+          ),
+          'delete' => array(
+            'enabled' => '1',
+          ),
+          'index' => array(
+            'enabled' => '1',
+          ),
+          'update' => array(
+            'enabled' => '1',
+          ),
+        ),
+        'actions' => array(
+          'create_raw' => array(
+            'enabled' => '1',
+          ),
+        ),
+      ),
+    );
+    $endpoint->debug = 1;
+    $endpoint->export_type = FALSE;
+    services_endpoint_save($endpoint);
+    $endpoint = services_endpoint_load($endpoint->name);
+    $this->assertTrue($endpoint->name == $edit['name'], 'Endpoint successfully created');
+    return $endpoint;
+  }
+
+  /**
+   * Tests file creation.
+   */
+  public function testFileUpdate() {
+    $this->privilegedUser = $this->drupalCreateUser(array('create files'));
+    $this->drupalLogin($this->privilegedUser);
+
+    // Get a test file.
+    $testfiles = $this->drupalGetTestFiles('php');
+    $testfile = current($testfiles);
+
+    // Setup file to be created.
+    $filepath = file_default_scheme() . '://' . rand() . '/' . rand() . '/' . $testfile->filename;
+    $file_data = array(
+      'uid' => '0',
+      'filesize' => filesize($testfile->uri),
+      'filename' => $testfile->filename,
+      'filepath' => $filepath,
+      'file' => base64_encode(file_get_contents($testfile->uri)),
+      'uuid' => 'ee26fe5d-f781-4a38-bfe0-8bb350b90073',
+      'type' => 'image',
+      'filemime' => 'text/plain',
+      'uri' => $testfile->uri,
+    );
+
+    $response = $this->servicesPut($this->endpoint->path . '/file/create', $file_data);
+
+    // Get the saved file's extension.
+    $file = file_load($response['body']->fid);
+    $name = explode('.', $file->filename);
+    $last = array_pop($name);
+    $extension = strtolower($last);
+
+    $this->assertNotEqual('php', $extension, 'File was not created with a "php" extension.', 'UUID: File Create');
+  }
+
+}

+ 9 - 4
sites/all/modules/uuid/uuid_services/uuid_services.info

@@ -7,9 +7,14 @@ dependencies[] = services
 dependencies[] = uuid
 dependencies[] = uuid
 dependencies[] = entity
 dependencies[] = entity
 
 
-; Information added by drupal.org packaging script on 2013-02-03
-version = "7.x-1.0-alpha3+52-dev"
+test_dependencies[] = services
+test_dependencies[] = entity
+test_dependencies[] = file
+test_dependencies[] = field
+test_dependencies[] = file_entity
+
+; Information added by Drupal.org packaging script on 2018-07-19
+version = "7.x-1.2"
 core = "7.x"
 core = "7.x"
 project = "uuid"
 project = "uuid"
-datestamp = "1359858369"
-
+datestamp = "1531990689"

+ 14 - 0
sites/all/modules/uuid/uuid_services/uuid_services.install

@@ -0,0 +1,14 @@
+<?php
+
+/**
+ * @file
+ * UUID module installation functions.
+ */
+
+/**
+ * Implements hook_uninstall().
+ */
+function uuid_services_uninstall() {
+  variable_del('uuid_services_support_all_entity_types');
+  variable_del('uuid_services_allowed_media_mimes');
+}

+ 60 - 24
sites/all/modules/uuid/uuid_services/uuid_services.module

@@ -1,5 +1,33 @@
 <?php
 <?php
 
 
+/**
+ * @file
+ * UUID Services module functions.
+ */
+
+/**
+ * Defines defaults for UUID_SERVICES_ALLOWED_MEDIA_MIMES.
+ */
+define('UUID_SERVICES_DEFAULT_ALLOWED_MEDIA_MIMES',
+'video/brightcove
+video/youtube'
+);
+
+/**
+ * Implements hook_menu().
+ */
+function uuid_services_menu() {
+  $items['admin/config/services/uuid-services'] = array(
+    'title' => 'UUID Services',
+    'description' => 'Configure settings for UUID Services.',
+    'access arguments' => array('administer services'),
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('uuid_services_settings'),
+    'file' => 'uuid_services.admin.inc',
+  );
+  return $items;
+}
+
 /**
 /**
  * Implements hook_services_resources_alter().
  * Implements hook_services_resources_alter().
  *
  *
@@ -14,7 +42,7 @@
  */
  */
 function uuid_services_services_resources_alter(&$resources, &$endpoint) {
 function uuid_services_services_resources_alter(&$resources, &$endpoint) {
   foreach (entity_get_info() as $entity_type => $entity_info) {
   foreach (entity_get_info() as $entity_type => $entity_info) {
-    if (isset($entity_info['uuid']) && $entity_info['uuid'] == TRUE && isset($resources[$entity_type])) {
+    if (isset($entity_info['uuid']) && $entity_info['uuid'] == TRUE && (isset($resources[$entity_type]) || variable_get('uuid_services_support_all_entity_types', FALSE))) {
       unset($resources[$entity_type]['operations']['create']);
       unset($resources[$entity_type]['operations']['create']);
 
 
       // Alter 'retrieve' method to use UUID enabled functions and arguments.
       // Alter 'retrieve' method to use UUID enabled functions and arguments.
@@ -126,6 +154,22 @@ function _uuid_services_entity_update($entity_type, $uuid, $entity) {
     else {
     else {
       $entity = (object) $entity;
       $entity = (object) $entity;
     }
     }
+    $entity->uuid_services = TRUE;
+    // Check that the mime type is whitelisted.
+    $valid_media_mimes = variable_get('uuid_services_allowed_media_mimes', UUID_SERVICES_DEFAULT_ALLOWED_MEDIA_MIMES);
+
+    // Sanitize file user input.
+    if ($entity_type == 'file') {
+      // We have to make sure to whitelist mime types, to avoid the video files
+      // getting converted into text files, when deployed from one env to other.
+      if (!in_array($entity->filemime, preg_split('/\r?\n/', $valid_media_mimes))) {
+        $entity->filename = _services_file_check_name_extension($entity->filename);
+        $entity->uri = _services_file_check_destination_uri($entity->uri);
+        if (!empty($entity->filepath)) {
+          $entity->filepath = _services_file_check_destination($entity->filepath);
+        }
+      }
+    }
     entity_uuid_save($entity_type, $entity);
     entity_uuid_save($entity_type, $entity);
     return $entity;
     return $entity;
   }
   }
@@ -142,7 +186,15 @@ function _uuid_services_entity_update($entity_type, $uuid, $entity) {
  */
  */
 function _uuid_services_entity_delete($entity_type, $uuid) {
 function _uuid_services_entity_delete($entity_type, $uuid) {
   try {
   try {
-    $return = entity_uuid_delete($entity_type, array($uuid));
+    $uuid_exist = (bool) entity_get_id_by_uuid($entity_type, array($uuid));
+    if (!$uuid_exist) {
+      /* UUID not found. Don't try to delete something that doesn't exist. */
+      $args = array('@uuid' => $uuid, '@type' => $entity_type);
+      watchdog('uuid_services', 'UUID @uuid not found for entity type @type', $args, WATCHDOG_WARNING);
+      return TRUE;
+    }
+
+    $return = entity_uuid_delete($entity_type, array($uuid)) !== FALSE;
     return $return;
     return $return;
   }
   }
   catch (Exception $exception) {
   catch (Exception $exception) {
@@ -154,14 +206,14 @@ function _uuid_services_entity_delete($entity_type, $uuid) {
 /**
 /**
  * Access callback.
  * Access callback.
  *
  *
- * @param $op
+ * @param string $op
  *   The operation we are trying to do on the entity. Can only be:
  *   The operation we are trying to do on the entity. Can only be:
  *   - "view"
  *   - "view"
  *   - "update"
  *   - "update"
  *   - "delete"
  *   - "delete"
  *   See 'uuid_services_services_resources_alter()' for an explanation why
  *   See 'uuid_services_services_resources_alter()' for an explanation why
  *   'create' is missing.
  *   'create' is missing.
- * @param $args
+ * @param array $args
  *   The arguments passed to the method. The keys are holding the following:
  *   The arguments passed to the method. The keys are holding the following:
  *   0. <entity_type>
  *   0. <entity_type>
  *   1. <uuid>
  *   1. <uuid>
@@ -182,7 +234,7 @@ function _uuid_services_entity_access($op, $args) {
       entity_make_entity_local($entity_type, $entity);
       entity_make_entity_local($entity_type, $entity);
     }
     }
     // Fetch the local entity if we've got an id.
     // Fetch the local entity if we've got an id.
-    elseif (!empty($entity_id)) {
+    elseif (!empty($entity_ids)) {
       $entities = entity_load($entity_type, $entity_ids);
       $entities = entity_load($entity_type, $entity_ids);
       $entity = reset($entities);
       $entity = reset($entities);
     }
     }
@@ -192,10 +244,9 @@ function _uuid_services_entity_access($op, $args) {
     if ($op == 'update' && empty($entity_ids)) {
     if ($op == 'update' && empty($entity_ids)) {
       $op = 'create';
       $op = 'create';
     }
     }
-    // Taxonomy and Comment module uses 'edit' instead of 'update'.
-    // Oh, how I love Drupal consistency.
-    if (($entity_type == 'taxonomy_term' || $entity_type == 'comment') && $op == 'update') {
-      $op = 'edit';
+    // If the user doesn't exist return 406 like services does.
+    if (($entity_type == 'user' && empty($entity) && $op == 'view')) {
+      return services_error(t('There is no user with UUID @uuid.', array('@uuid' => $args[1])), 406);;
     }
     }
     // The following code is taken from entity_access() with some extra logic
     // The following code is taken from entity_access() with some extra logic
     // to handle the case where an entity type is not defining an access
     // to handle the case where an entity type is not defining an access
@@ -211,18 +262,3 @@ function _uuid_services_entity_access($op, $args) {
     return services_error($exception, 406, $entity_type);
     return services_error($exception, 406, $entity_type);
   }
   }
 }
 }
-
-/**
- * Implements hook_services_resources().
- */
-function uuid_services_services_resources() {
-  module_load_include('inc', 'uuid_services', 'resources/field_collection.resource');
-
-  $resources = array(
-    '#api_version' => 3002,
-  );
-
-  $resources += _field_collection_resource_definition();
-
-  return $resources;
-}

+ 1 - 0
sites/all/modules/uuid/uuid_services_example/uuid_services_example.features.inc

@@ -1,4 +1,5 @@
 <?php
 <?php
+
 /**
 /**
  * @file
  * @file
  * uuid_services_example.features.inc
  * uuid_services_example.features.inc

+ 15 - 14
sites/all/modules/uuid/uuid_services_example/uuid_services_example.info

@@ -1,17 +1,18 @@
-core = "7.x"
-dependencies[] = "rest_server"
-dependencies[] = "services"
-dependencies[] = "uuid"
-dependencies[] = "uuid_services"
-description = "Example feature of a UUID service. Works well with the Deploy Example feature as a client."
-features[ctools][] = "services:services:3"
-features[services_endpoint][] = "uuid_services_example"
-name = "UUID Services Example"
-package = "Features"
+name = UUID Services Example
+description = Example feature of a UUID service. Works well with the Deploy Example feature as a client.
+core = 7.x
+package = Features
+php = 5.2.4
+dependencies[] = rest_server
+dependencies[] = services
+dependencies[] = uuid
+dependencies[] = uuid_services
+features[ctools][] = services:services:3
+features[features_api][] = api:2
+features[services_endpoint][] = uuid_services_example
 
 
-; Information added by drupal.org packaging script on 2013-02-03
-version = "7.x-1.0-alpha3+52-dev"
+; Information added by Drupal.org packaging script on 2018-07-19
+version = "7.x-1.2"
 core = "7.x"
 core = "7.x"
 project = "uuid"
 project = "uuid"
-datestamp = "1359858369"
-
+datestamp = "1531990689"

+ 2 - 1
sites/all/modules/uuid/uuid_services_example/uuid_services_example.module

@@ -1,7 +1,8 @@
 <?php
 <?php
+
 /**
 /**
  * @file
  * @file
  * Code for the UUID Services Example feature.
  * Code for the UUID Services Example feature.
  */
  */
 
 
-include_once('uuid_services_example.features.inc');
+include_once 'uuid_services_example.features.inc';

+ 21 - 9
sites/all/modules/uuid/uuid_services_example/uuid_services_example.services.inc

@@ -1,4 +1,5 @@
 <?php
 <?php
+
 /**
 /**
  * @file
  * @file
  * uuid_services_example.services.inc
  * uuid_services_example.services.inc
@@ -10,7 +11,7 @@
 function uuid_services_example_default_services_endpoint() {
 function uuid_services_example_default_services_endpoint() {
   $export = array();
   $export = array();
 
 
-  $endpoint = new stdClass;
+  $endpoint = new stdClass();
   $endpoint->disabled = FALSE; /* Edit this to true to make a default endpoint disabled initially */
   $endpoint->disabled = FALSE; /* Edit this to true to make a default endpoint disabled initially */
   $endpoint->api_version = 3;
   $endpoint->api_version = 3;
   $endpoint->name = 'uuid_services_example';
   $endpoint->name = 'uuid_services_example';
@@ -25,7 +26,6 @@ function uuid_services_example_default_services_endpoint() {
       'bencode' => FALSE,
       'bencode' => FALSE,
       'jsonp' => FALSE,
       'jsonp' => FALSE,
       'php' => FALSE,
       'php' => FALSE,
-      'rss' => FALSE,
       'xml' => FALSE,
       'xml' => FALSE,
       'yaml' => FALSE,
       'yaml' => FALSE,
     ),
     ),
@@ -35,49 +35,61 @@ function uuid_services_example_default_services_endpoint() {
       'multipart/form-data' => TRUE,
       'multipart/form-data' => TRUE,
       'application/vnd.php.serialized' => FALSE,
       'application/vnd.php.serialized' => FALSE,
       'application/x-yaml' => FALSE,
       'application/x-yaml' => FALSE,
+      'application/xml' => FALSE,
+      'text/xml' => FALSE,
     ),
     ),
   );
   );
   $endpoint->resources = array(
   $endpoint->resources = array(
     'comment' => array(
     'comment' => array(
       'operations' => array(
       'operations' => array(
         'update' => array(
         'update' => array(
-          'enabled' => 1,
+          'enabled' => '1',
         ),
         ),
       ),
       ),
     ),
     ),
     'file' => array(
     'file' => array(
       'operations' => array(
       'operations' => array(
         'update' => array(
         'update' => array(
-          'enabled' => 1,
+          'enabled' => '1',
         ),
         ),
       ),
       ),
     ),
     ),
     'node' => array(
     'node' => array(
       'operations' => array(
       'operations' => array(
         'update' => array(
         'update' => array(
-          'enabled' => 1,
+          'enabled' => '1',
         ),
         ),
       ),
       ),
     ),
     ),
     'taxonomy_term' => array(
     'taxonomy_term' => array(
       'operations' => array(
       'operations' => array(
         'update' => array(
         'update' => array(
-          'enabled' => 1,
+          'enabled' => '1',
         ),
         ),
       ),
       ),
     ),
     ),
     'user' => array(
     'user' => array(
       'operations' => array(
       'operations' => array(
         'update' => array(
         'update' => array(
-          'enabled' => 1,
+          'enabled' => '1',
         ),
         ),
       ),
       ),
       'actions' => array(
       'actions' => array(
         'login' => array(
         'login' => array(
-          'enabled' => 1,
+          'enabled' => '1',
+          'settings' => array(
+            'services' => array(
+              'resource_api_version' => '1.0',
+            ),
+          ),
         ),
         ),
         'logout' => array(
         'logout' => array(
-          'enabled' => 1,
+          'enabled' => '1',
+          'settings' => array(
+            'services' => array(
+              'resource_api_version' => '1.0',
+            ),
+          ),
         ),
         ),
       ),
       ),
     ),
     ),

+ 43 - 18
sites/all/modules/xmlsitemap/README.txt

@@ -1,40 +1,53 @@
-
 CONTENTS OF THIS FILE
 CONTENTS OF THIS FILE
 ---------------------
 ---------------------
 
 
  * Introduction
  * Introduction
- * Installing
+ * Requirements
+ * Installation
+ * Configuration
  * Uninstalling
  * Uninstalling
  * Frequently Asked Questions (FAQ)
  * Frequently Asked Questions (FAQ)
  * Known Issues
  * Known Issues
  * More Information
  * More Information
  * How Can You Contribute?
  * How Can You Contribute?
+ * Maintainers
 
 
 
 
 INTRODUCTION
 INTRODUCTION
 ------------
 ------------
 
 
-Current Maintainer: Dave Reid <http://drupal.org/user/53892>
-Co-maintainer: Kiam <http://drupal.org/user/55077>
-Co-maintainer: Earnie <http://drupal.org/user/86710>
-Co-maintainer: Darren Oh <http://drupal.org/user/30772>
-Original Author: Matthew Loar <http://drupal.org/user/24879>
-
 XML Sitemap automatically creates a sitemap that conforms to the sitemaps.org
 XML Sitemap automatically creates a sitemap that conforms to the sitemaps.org
 specification. This helps search engines keep their search results up to date.
 specification. This helps search engines keep their search results up to date.
 
 
 
 
-INSTALLING
-----------
+REQUIREMENTS
+------------
+
+No special requirements
+
+
+INSTALLATION
+------------
 
 
-See http://drupal.org/getting-started/install-contrib for instructions on
-how to install or update Drupal modules.
+Install as you would normally install a contributed Drupal module. See:
+https://drupal.org/documentation/install/modules-themes/modules-7 for further
+information.
 
 
 Once XML Sitemap is installed and enabled, you can adjust the settings for your
 Once XML Sitemap is installed and enabled, you can adjust the settings for your
 site's sitemap at admin/config/search/xmlsitemap. Your can view your site's
 site's sitemap at admin/config/search/xmlsitemap. Your can view your site's
 sitemap at http://yoursite.com/sitemap.xml.
 sitemap at http://yoursite.com/sitemap.xml.
 
 
-It is highly recommended that you have clean URLs enabled for this module.
+It is highly recommended that you have clean URLs enabled for this project.
+
+
+CONFIGURATION
+-------------
+
+ * Configure your XML sitemap in:
+   Configuration » Search and metadata »XML sitemap
+
+   - Check your XML site
+   - Click in Update for update the XML values.
 
 
 
 
 UNINSTALLING
 UNINSTALLING
@@ -43,7 +56,7 @@ UNINSTALLING
 Because Drupal does not uninstall modules in reverse order of their
 Because Drupal does not uninstall modules in reverse order of their
 dependencies, if you want to uninstall all the XML sitemap modules, be sure to
 dependencies, if you want to uninstall all the XML sitemap modules, be sure to
 disable and uninstall all the sub-modules before the base XML sitemap module.
 disable and uninstall all the sub-modules before the base XML sitemap module.
-To help fix this bug in Drupal core, visit http://drupal.org/node/151452.
+To help fix this bug in Drupal core, visit https://www.drupal.org/node/151452.
 
 
 
 
 FREQUENTLY ASKED QUESTIONS (FAQ)
 FREQUENTLY ASKED QUESTIONS (FAQ)
@@ -55,17 +68,17 @@ FREQUENTLY ASKED QUESTIONS (FAQ)
 KNOWN ISSUES
 KNOWN ISSUES
 ------------
 ------------
 
 
-- See http://drupal.org/node/482550 for a list of the current known issues.
+- See https://www.drupal.org/node/482550 for a list of the current known issues.
 
 
 
 
 MORE INFORMATION
 MORE INFORMATION
 ----------------
 ----------------
 
 
 - To issue any bug reports, feature or support requests, see the module issue
 - To issue any bug reports, feature or support requests, see the module issue
-  queue at http://drupal.org/project/issues/xmlsitemap.
+  queue at https://www.drupal.org/project/issues/xmlsitemap.
 
 
 - For additional documentation, see the online module handbook at
 - For additional documentation, see the online module handbook at
-  http://drupal.org/handbook/modules/xmlsitemap.
+  https://www.drupal.org/handbook/modules/xmlsitemap.
 
 
 - You can view the sitemap.org specification at http://sitemaps.org.
 - You can view the sitemap.org specification at http://sitemaps.org.
 
 
@@ -74,7 +87,7 @@ HOW CAN YOU CONTRIBUTE?
 -----------------------
 -----------------------
 
 
 - Report any bugs, feature requests, etc. in the issue tracker.
 - Report any bugs, feature requests, etc. in the issue tracker.
-  http://drupal.org/project/issues/xmlsitemap
+  https://www.drupal.org/project/issues/xmlsitemap
 
 
 - Help translate this module.
 - Help translate this module.
   http://localize.drupal.org/translate/projects/xmlsitemap
   http://localize.drupal.org/translate/projects/xmlsitemap
@@ -84,3 +97,15 @@ HOW CAN YOU CONTRIBUTE?
 
 
 - Help keep development active by dontating to the developer.
 - Help keep development active by dontating to the developer.
   http://davereid.chipin.com/
   http://davereid.chipin.com/
+
+
+MAINTAINERS
+-----------
+
+Current maintainers:
+ * Current Maintainer: Dave Reid <https://www.drupal.org/user/53892>
+ * Co-maintainer: Renato Gonçalves RenatoG <https://www.drupal.org/user/3326031>
+ * Co-maintainer: Kiam <https://www.drupal.org/user/55077>
+ * Co-maintainer: Earnie <https://www.drupal.org/user/86710>
+ * Co-maintainer: Darren Oh <https://www.drupal.org/user/30772>
+ * Original Author: Matthew Loar <https://www.drupal.org/user/24879>

+ 91 - 55
sites/all/modules/xmlsitemap/xmlsitemap.admin.inc

@@ -35,8 +35,6 @@ function xmlsitemap_sitemap_list_form() {
   $form['operations']['submit'] = array(
   $form['operations']['submit'] = array(
     '#type' => 'submit',
     '#type' => 'submit',
     '#value' => t('Update'),
     '#value' => t('Update'),
-    //'#validate' => array('xmlsitemap_sitemap_list_form_validate'),
-    //'#submit' => array('xmlsitemap_sitemap_list_form_submit'),
   );
   );
 
 
   $contexts = xmlsitemap_get_context_info();
   $contexts = xmlsitemap_get_context_info();
@@ -48,7 +46,11 @@ function xmlsitemap_sitemap_list_form() {
       $header['context_' . $context_key] = $context_info['label'];
       $header['context_' . $context_key] = $context_info['label'];
     }
     }
   }
   }
-  $header['updated'] = array('data' => t('Last updated'), 'field' => 'updated', 'sort' => 'asc');
+  $header['updated'] = array(
+    'data' => t('Last updated'),
+    'field' => 'updated',
+    'sort' => 'asc',
+  );
   $header['links'] = array('data' => t('Links'), 'field' => 'links');
   $header['links'] = array('data' => t('Links'), 'field' => 'links');
   $header['chunks'] = array('data' => t('Pages'), 'field' => 'chunks');
   $header['chunks'] = array('data' => t('Pages'), 'field' => 'chunks');
   $header['operations'] = array('data' => t('Operations'));
   $header['operations'] = array('data' => t('Operations'));
@@ -82,8 +84,7 @@ function xmlsitemap_sitemap_list_form() {
     $options[$smid]['chunks'] = $sitemap->updated ? $sitemap->chunks : '-';
     $options[$smid]['chunks'] = $sitemap->updated ? $sitemap->chunks : '-';
 
 
     // @todo Highlight sitemaps that need updating.
     // @todo Highlight sitemaps that need updating.
-    //$options[$smid]['#attributes']['class'][] = 'warning';
-
+    // $options[$smid]['#attributes']['class'][] = 'warning';
     $operations = array();
     $operations = array();
     $operations['edit'] = xmlsitemap_get_operation_link('admin/config/search/xmlsitemap/edit/' . $smid, array('title' => t('Edit'), 'modal' => TRUE));
     $operations['edit'] = xmlsitemap_get_operation_link('admin/config/search/xmlsitemap/edit/' . $smid, array('title' => t('Edit'), 'modal' => TRUE));
     $operations['delete'] = xmlsitemap_get_operation_link('admin/config/search/xmlsitemap/delete/' . $smid, array('title' => t('Delete'), 'modal' => TRUE));
     $operations['delete'] = xmlsitemap_get_operation_link('admin/config/search/xmlsitemap/delete/' . $smid, array('title' => t('Delete'), 'modal' => TRUE));
@@ -151,12 +152,18 @@ function xmlsitemap_sitemap_list_form_submit($form, &$form_state) {
     call_user_func_array($function, $args);
     call_user_func_array($function, $args);
 
 
     $count = count($form_state['values']['sitemaps']);
     $count = count($form_state['values']['sitemaps']);
-    //watchdog('xmlsitemap', '@action @count XML sitemaps.', array('@action' => $operation['action past'], '@count' => $count));
-    drupal_set_message(format_plural(count($sitemaps), '@action @count XML sitemap.', '@action @count XML sitemaps.', array('@action' => $operation['action past'], '@count' => $count)));
-    //$form_state['redirect'] = 'admin/config/search/xmlsitemap';
+    drupal_set_message(
+      format_plural(
+        count($sitemaps), '@action @count XML sitemap.', '@action @count XML sitemaps.',
+        array('@action' => $operation['action past'], '@count' => $count)
+      )
+    );
   }
   }
 }
 }
 
 
+/**
+ * Edit Form.
+ */
 function xmlsitemap_sitemap_edit_form(array $form, array &$form_state, stdClass $sitemap = NULL) {
 function xmlsitemap_sitemap_edit_form(array $form, array &$form_state, stdClass $sitemap = NULL) {
   _xmlsitemap_set_breadcrumb();
   _xmlsitemap_set_breadcrumb();
 
 
@@ -196,6 +203,9 @@ function xmlsitemap_sitemap_edit_form(array $form, array &$form_state, stdClass
   return $form;
   return $form;
 }
 }
 
 
+/**
+ * Edit Form Pre Render.
+ */
 function xmlsitemap_sitemap_edit_form_pre_render($form) {
 function xmlsitemap_sitemap_edit_form_pre_render($form) {
   $visible_children = element_get_visible_children($form['context']);
   $visible_children = element_get_visible_children($form['context']);
   if (empty($visible_children)) {
   if (empty($visible_children)) {
@@ -207,6 +217,9 @@ function xmlsitemap_sitemap_edit_form_pre_render($form) {
   return $form;
   return $form;
 }
 }
 
 
+/**
+ * Edit form validate.
+ */
 function xmlsitemap_sitemap_edit_form_validate($form, &$form_state) {
 function xmlsitemap_sitemap_edit_form_validate($form, &$form_state) {
   // If there are no context options, the $form_state['values']['context']
   // If there are no context options, the $form_state['values']['context']
   // disappears.
   // disappears.
@@ -217,6 +230,9 @@ function xmlsitemap_sitemap_edit_form_validate($form, &$form_state) {
   }
   }
 }
 }
 
 
+/**
+ * Edit Form Submit.
+ */
 function xmlsitemap_sitemap_edit_form_submit($form, &$form_state) {
 function xmlsitemap_sitemap_edit_form_submit($form, &$form_state) {
   form_state_values_clean($form_state);
   form_state_values_clean($form_state);
   $sitemap = (object) $form_state['values'];
   $sitemap = (object) $form_state['values'];
@@ -225,6 +241,9 @@ function xmlsitemap_sitemap_edit_form_submit($form, &$form_state) {
   $form_state['redirect'] = 'admin/config/search/xmlsitemap';
   $form_state['redirect'] = 'admin/config/search/xmlsitemap';
 }
 }
 
 
+/**
+ * Delete form.
+ */
 function xmlsitemap_sitemap_delete_form(array $form, array &$form_state, stdClass $sitemap) {
 function xmlsitemap_sitemap_delete_form(array $form, array &$form_state, stdClass $sitemap) {
   _xmlsitemap_set_breadcrumb();
   _xmlsitemap_set_breadcrumb();
 
 
@@ -248,6 +267,9 @@ function xmlsitemap_sitemap_delete_form(array $form, array &$form_state, stdClas
   );
   );
 }
 }
 
 
+/**
+ * Delete form submit.
+ */
 function xmlsitemap_sitemap_delete_form_submit($form, $form_state) {
 function xmlsitemap_sitemap_delete_form_submit($form, $form_state) {
   xmlsitemap_sitemap_delete($form_state['values']['smid']);
   xmlsitemap_sitemap_delete($form_state['values']['smid']);
   drupal_set_message(t('The sitemap has been deleted.'));
   drupal_set_message(t('The sitemap has been deleted.'));
@@ -261,10 +283,22 @@ function xmlsitemap_sitemap_delete_form_submit($form, $form_state) {
  * @see xmlsitemap_settings_form_validate()
  * @see xmlsitemap_settings_form_validate()
  */
  */
 function xmlsitemap_settings_form($form, &$form_state) {
 function xmlsitemap_settings_form($form, &$form_state) {
+  global $base_url;
   $form['xmlsitemap_minimum_lifetime'] = array(
   $form['xmlsitemap_minimum_lifetime'] = array(
     '#type' => 'select',
     '#type' => 'select',
     '#title' => t('Minimum sitemap lifetime'),
     '#title' => t('Minimum sitemap lifetime'),
-    '#options' => array(0 => t('No minimum')) + drupal_map_assoc(array(300, 900, 1800, 3600, 10800, 21600, 43200, 86400, 172800, 259200, 604800), 'format_interval'),
+    '#options' => array(0 => t('No minimum')) + drupal_map_assoc(array(300,
+      900,
+      1800,
+      3600,
+      10800,
+      21600,
+      43200,
+      86400,
+      172800,
+      259200,
+      604800,
+    ), 'format_interval'),
     '#description' => t('The minimum amount of time that will elapse before the sitemaps are regenerated. The sitemaps will also only be regenerated on cron if any links have been added, updated, or deleted.') . '<br />' . t('Recommended value: %value.', array('%value' => t('1 day'))),
     '#description' => t('The minimum amount of time that will elapse before the sitemaps are regenerated. The sitemaps will also only be regenerated on cron if any links have been added, updated, or deleted.') . '<br />' . t('Recommended value: %value.', array('%value' => t('1 day'))),
     '#default_value' => variable_get('xmlsitemap_minimum_lifetime', 0),
     '#default_value' => variable_get('xmlsitemap_minimum_lifetime', 0),
   );
   );
@@ -288,16 +322,19 @@ function xmlsitemap_settings_form($form, &$form_state) {
     '#collapsed' => !variable_get('xmlsitemap_developer_mode', 0),
     '#collapsed' => !variable_get('xmlsitemap_developer_mode', 0),
     '#weight' => 10,
     '#weight' => 10,
   );
   );
-  //$form['advanced']['xmlsitemap_gz'] = array(
-  //  '#type' => 'checkbox',
-  //  '#title' => t('Generate additional compressed sitemaps using gzip.'),
-  //  '#default_value' => xmlsitemap_var('gz'),
-  //  '#disabled' => !function_exists('gzencode'),
-  //);
   $form['advanced']['xmlsitemap_chunk_size'] = array(
   $form['advanced']['xmlsitemap_chunk_size'] = array(
     '#type' => 'select',
     '#type' => 'select',
     '#title' => t('Number of links in each sitemap page'),
     '#title' => t('Number of links in each sitemap page'),
-    '#options' => array('auto' => t('Automatic (recommended)')) + drupal_map_assoc(array(100, 500, 1000, 2500, 5000, 10000, 25000, XMLSITEMAP_MAX_SITEMAP_LINKS)),
+    '#options' => array('auto' => t('Automatic (recommended)')) + drupal_map_assoc(array(
+      100,
+      500,
+      1000,
+      2500,
+      5000,
+      10000,
+      25000,
+      XMLSITEMAP_MAX_SITEMAP_LINKS,
+    )),
     '#default_value' => xmlsitemap_var('chunk_size'),
     '#default_value' => xmlsitemap_var('chunk_size'),
     // @todo This description is not clear.
     // @todo This description is not clear.
     '#description' => t('If there are problems with rebuilding the sitemap, you may want to manually set this value. If you have more than @max links, an index with multiple sitemap pages will be generated. There is a maximum of @max sitemap pages.', array('@max' => XMLSITEMAP_MAX_SITEMAP_LINKS)),
     '#description' => t('If there are problems with rebuilding the sitemap, you may want to manually set this value. If you have more than @max links, an index with multiple sitemap pages will be generated. There is a maximum of @max sitemap pages.', array('@max' => XMLSITEMAP_MAX_SITEMAP_LINKS)),
@@ -305,7 +342,18 @@ function xmlsitemap_settings_form($form, &$form_state) {
   $form['advanced']['xmlsitemap_batch_limit'] = array(
   $form['advanced']['xmlsitemap_batch_limit'] = array(
     '#type' => 'select',
     '#type' => 'select',
     '#title' => t('Maximum number of sitemap links to process at once'),
     '#title' => t('Maximum number of sitemap links to process at once'),
-    '#options' => drupal_map_assoc(array(5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000)),
+    '#options' => drupal_map_assoc(array(
+      5,
+      10,
+      25,
+      50,
+      100,
+      250,
+      500,
+      1000,
+      2500,
+      5000,
+    )),
     '#default_value' => xmlsitemap_var('batch_limit'),
     '#default_value' => xmlsitemap_var('batch_limit'),
     '#description' => t('If you have problems running cron or rebuilding the sitemap, you may want to lower this value.'),
     '#description' => t('If you have problems running cron or rebuilding the sitemap, you may want to lower this value.'),
   );
   );
@@ -325,7 +373,7 @@ function xmlsitemap_settings_form($form, &$form_state) {
   $form['advanced']['xmlsitemap_base_url'] = array(
   $form['advanced']['xmlsitemap_base_url'] = array(
     '#type' => 'textfield',
     '#type' => 'textfield',
     '#title' => t('Default base URL'),
     '#title' => t('Default base URL'),
-    '#default_value' => variable_get('xmlsitemap_base_url', $GLOBALS['base_url']),
+    '#default_value' => variable_get('xmlsitemap_base_url', $base_url),
     '#size' => 30,
     '#size' => 30,
     '#description' => t('This is the default base URL used for sitemaps and sitemap links.'),
     '#description' => t('This is the default base URL used for sitemaps and sitemap links.'),
     '#required' => TRUE,
     '#required' => TRUE,
@@ -362,7 +410,11 @@ function xmlsitemap_settings_form($form, &$form_state) {
       'changefreq' => t('Change frequency: @changfreq', array('@changfreq' => '<changefreq>')),
       'changefreq' => t('Change frequency: @changfreq', array('@changfreq' => '<changefreq>')),
       'priority' => t('Priority: @priority', array('@priority' => '<priority>')),
       'priority' => t('Priority: @priority', array('@priority' => '<priority>')),
     ),
     ),
-    '#default_value' => drupal_map_assoc(variable_get('xmlsitemap_output_elements', array('lastmod', 'changefreq', 'priority'))),
+    '#default_value' => drupal_map_assoc(variable_get('xmlsitemap_output_elements', array(
+      'lastmod',
+      'changefreq',
+      'priority',
+    ))),
   );
   );
 
 
   $form['xmlsitemap_settings'] = array(
   $form['xmlsitemap_settings'] = array(
@@ -425,7 +477,7 @@ function xmlsitemap_settings_form_validate($form, &$form_state) {
 }
 }
 
 
 /**
 /**
- * Submit handler;
+ * Submit handler;.
  *
  *
  * @see xmlsitemap_settings_form()
  * @see xmlsitemap_settings_form()
  */
  */
@@ -570,17 +622,6 @@ function xmlsitemap_add_form_entity_summary(&$form, $entity, array $entity_info)
  */
  */
 function xmlsitemap_add_link_bundle_settings(array &$form, array &$form_state, $entity, $bundle) {
 function xmlsitemap_add_link_bundle_settings(array &$form, array &$form_state, $entity, $bundle) {
   $entity_info = xmlsitemap_get_link_info($entity);
   $entity_info = xmlsitemap_get_link_info($entity);
-
-  //if (!isset($bundle) && isset($entity_info['bundle keys']['bundle'])) {
-  //  $bundle_key = $entity_info['bundle keys']['bundle'];
-  //  if (isset($form[$bundle_key]['#value'])) {
-  //    $bundle = $form[$bundle_key]['#value'];
-  //  }
-  //  elseif (isset($form[$bundle_key]['#default_value'])) {
-  //    $bundle = $form[$bundle_key]['#default_value'];
-  //  }
-  //}
-
   $bundle_info = xmlsitemap_link_bundle_load($entity, $bundle);
   $bundle_info = xmlsitemap_link_bundle_load($entity, $bundle);
 
 
   $form['xmlsitemap'] = array(
   $form['xmlsitemap'] = array(
@@ -641,6 +682,9 @@ function xmlsitemap_add_link_bundle_settings(array &$form, array &$form_state, $
   }
   }
 }
 }
 
 
+/**
+ * Link bundle settings form.
+ */
 function xmlsitemap_link_bundle_settings_form(array $form, array &$form_state, array $bundle) {
 function xmlsitemap_link_bundle_settings_form(array $form, array &$form_state, array $bundle) {
   if (empty($form_state['ajax']) && $admin_path = xmlsitemap_get_bundle_path($bundle['entity'], $bundle['bundle'])) {
   if (empty($form_state['ajax']) && $admin_path = xmlsitemap_get_bundle_path($bundle['entity'], $bundle['bundle'])) {
     // If this is a non-ajax form, redirect to the bundle administration page.
     // If this is a non-ajax form, redirect to the bundle administration page.
@@ -649,7 +693,7 @@ function xmlsitemap_link_bundle_settings_form(array $form, array &$form_state, a
     drupal_goto($admin_path, array('query' => $destination));
     drupal_goto($admin_path, array('query' => $destination));
   }
   }
   else {
   else {
-    drupal_set_title( t('@bundle XML sitemap settings', array('@bundle' => $bundle['info']['label'])));
+    drupal_set_title(t('@bundle XML sitemap settings', array('@bundle' => $bundle['info']['label'])));
   }
   }
 
 
   $form = array();
   $form = array();
@@ -707,7 +751,7 @@ function xmlsitemap_add_form_link_options(array &$form, $entity, $bundle, $id) {
     '#title' => t('XML sitemap'),
     '#title' => t('XML sitemap'),
     '#collapsible' => TRUE,
     '#collapsible' => TRUE,
     '#collapsed' => !$link['status_override'] && !$link['priority_override'],
     '#collapsed' => !$link['status_override'] && !$link['priority_override'],
-    '#access' => user_access('administer xmlsitemap') || xmlsitemap_link_bundle_access($bundle_info),
+    '#access' => user_access('administer xmlsitemap') || user_access('use xmlsitemap') || xmlsitemap_link_bundle_access($bundle_info),
     '#group' => 'additional_settings',
     '#group' => 'additional_settings',
     '#attached' => array(
     '#attached' => array(
       'js' => array(
       'js' => array(
@@ -725,7 +769,12 @@ function xmlsitemap_add_form_link_options(array &$form, $entity, $bundle, $id) {
     $form['xmlsitemap']['description'] = array(
     $form['xmlsitemap']['description'] = array(
       '#prefix' => '<div class="description">',
       '#prefix' => '<div class="description">',
       '#suffix' => '</div>',
       '#suffix' => '</div>',
-      '#markup' => t('The default XML sitemap settings for this @bundle can be changed <a href="@link-type">here</a>.', array('@bundle' => drupal_strtolower($info['bundle label']), '@link-type' => url($path, array('query' => drupal_get_destination())))),
+      '#markup' => t('The default XML sitemap settings for this @bundle can be changed <a href="@link-type">here</a>.', array(
+        '@bundle' => drupal_strtolower($info['bundle label']),
+        '@link-type' => url($path, array(
+          'query' => drupal_get_destination(),
+        )),
+      )),
     );
     );
   }
   }
 
 
@@ -756,7 +805,7 @@ function xmlsitemap_add_form_link_options(array &$form, $entity, $bundle, $id) {
     '#value' => $link['status_override'],
     '#value' => $link['status_override'],
   );
   );
 
 
-  // Priority field
+  // Priority field.
   $form['xmlsitemap']['priority'] = array(
   $form['xmlsitemap']['priority'] = array(
     '#type' => 'select',
     '#type' => 'select',
     '#title' => t('Priority'),
     '#title' => t('Priority'),
@@ -784,21 +833,6 @@ function xmlsitemap_add_form_link_options(array &$form, $entity, $bundle, $id) {
     '#type' => 'value',
     '#type' => 'value',
     '#value' => $link['priority_override'],
     '#value' => $link['priority_override'],
   );
   );
-
-  // Other persistent fields.
-  //$form['xmlsitemap']['lastmod'] = array(
-  //  '#type' => 'value',
-  //  '#value' => $node->xmlsitemap['lastmod'],
-  //);
-  //$form['xmlsitemap']['changefreq'] = array(
-  //  '#type' => 'value',
-  //  '#value' => $node->xmlsitemap['changefreq'],
-  //);
-  //$form['xmlsitemap']['changecount'] = array(
-  //  '#type' => 'value',
-  //  '#value' => $node->xmlsitemap['changecount'],
-  //);
-
   // Add the submit handler to adjust the default values if selected.
   // Add the submit handler to adjust the default values if selected.
   $form += array('#submit' => array());
   $form += array('#submit' => array());
   if (!in_array('xmlsitemap_process_form_link_options', $form['#submit'])) {
   if (!in_array('xmlsitemap_process_form_link_options', $form['#submit'])) {
@@ -809,11 +843,12 @@ function xmlsitemap_add_form_link_options(array &$form, $entity, $bundle, $id) {
 /**
 /**
  * Get a list of priority options.
  * Get a list of priority options.
  *
  *
- * @param $default
+ * @param string $default
  *   Include a 'default' option.
  *   Include a 'default' option.
- * @param $guides
+ * @param string $guides
  *   Add helpful indicators for the highest, middle and lowest values.
  *   Add helpful indicators for the highest, middle and lowest values.
- * @return
+ *
+ * @return array
  *   An array of options.
  *   An array of options.
  */
  */
 function xmlsitemap_get_priority_options($default = NULL, $guides = TRUE) {
 function xmlsitemap_get_priority_options($default = NULL, $guides = TRUE) {
@@ -852,9 +887,10 @@ function xmlsitemap_get_priority_options($default = NULL, $guides = TRUE) {
 /**
 /**
  * Get a list of priority options.
  * Get a list of priority options.
  *
  *
- * @param $default
+ * @param string $default
  *   Include a 'default' option.
  *   Include a 'default' option.
- * @return
+ *
+ * @return array
  *   An array of options.
  *   An array of options.
  *
  *
  * @see _xmlsitemap_translation_strings()
  * @see _xmlsitemap_translation_strings()

+ 43 - 13
sites/all/modules/xmlsitemap/xmlsitemap.api.php

@@ -24,9 +24,9 @@ function hook_xmlsitemap_link_info() {
       'label' => 'My module',
       'label' => 'My module',
       'base table' => 'mymodule',
       'base table' => 'mymodule',
       'entity keys' => array(
       'entity keys' => array(
-        // Primary ID key on {base table}
+        // Primary ID key on {base table}.
         'id' => 'myid',
         'id' => 'myid',
-        // Subtype key on {base table}
+        // Subtype key on {base table}.
         'bundle' => 'mysubtype',
         'bundle' => 'mysubtype',
       ),
       ),
       'path callback' => 'mymodule_path',
       'path callback' => 'mymodule_path',
@@ -52,11 +52,29 @@ function hook_xmlsitemap_link_info() {
         'rebuild callback' => '',
         'rebuild callback' => '',
         // Callback function called from the XML sitemap settings page.
         // Callback function called from the XML sitemap settings page.
         'settings callback' => '',
         'settings callback' => '',
-      )
+      ),
     ),
     ),
   );
   );
 }
 }
 
 
+/**
+ * Act on a sitemap link being inserted or updated.
+ *
+ * This hook is currently invoked from xmlsitemap_node_node_update() before
+ * the node sitemap link is saved to the database with revoked access until
+ * the node permissions are checked in the cron.
+ *
+ * @param array $link
+ *   An array with the data of the sitemap link.
+ * @param array $context
+ *   An optional context array containing data related to the link.
+ */
+function hook_xmlsitemap_link_presave_alter(array &$link, array $context) {
+  if ($link['type'] == 'mymodule') {
+    $link['priority'] += 0.5;
+  }
+}
+
 /**
 /**
  * Alter the data of a sitemap link before the link is saved.
  * Alter the data of a sitemap link before the link is saved.
  *
  *
@@ -74,7 +92,7 @@ function hook_xmlsitemap_link_alter(array &$link, array $context) {
 /**
 /**
  * Inform modules that an XML sitemap link has been created.
  * Inform modules that an XML sitemap link has been created.
  *
  *
- * @param $link
+ * @param array $link
  *   Associative array defining an XML sitemap link as passed into
  *   Associative array defining an XML sitemap link as passed into
  *   xmlsitemap_link_save().
  *   xmlsitemap_link_save().
  * @param array $context
  * @param array $context
@@ -95,7 +113,7 @@ function hook_xmlsitemap_link_insert(array $link, array $context) {
 /**
 /**
  * Inform modules that an XML sitemap link has been updated.
  * Inform modules that an XML sitemap link has been updated.
  *
  *
- * @param $link
+ * @param array $link
  *   Associative array defining an XML sitemap link as passed into
  *   Associative array defining an XML sitemap link as passed into
  *   xmlsitemap_link_save().
  *   xmlsitemap_link_save().
  * @param array $context
  * @param array $context
@@ -127,6 +145,12 @@ function hook_xmlsitemap_rebuild_clear(array $types, $save_custom) {
     ->execute();
     ->execute();
 }
 }
 
 
+/**
+ * Respond to XML sitemap regeneration.
+ */
+function hook_xmlsitemap_regenerate_finished() {
+}
+
 /**
 /**
  * Index links for the XML sitemaps.
  * Index links for the XML sitemaps.
  */
  */
@@ -136,7 +160,7 @@ function hook_xmlsitemap_index_links($limit) {
 /**
 /**
  * Provide information about contexts available to XML sitemap.
  * Provide information about contexts available to XML sitemap.
  *
  *
- * @see hook_xmlsitemap_context_info_alter().
+ * @see hook_xmlsitemap_context_info_alter()
  */
  */
 function hook_xmlsitemap_context_info() {
 function hook_xmlsitemap_context_info() {
   $info['vocabulary'] = array(
   $info['vocabulary'] = array(
@@ -150,7 +174,7 @@ function hook_xmlsitemap_context_info() {
 /**
 /**
  * Alter XML sitemap context info.
  * Alter XML sitemap context info.
  *
  *
- * @see hook_xmlsitemap_context_info().
+ * @see hook_xmlsitemap_context_info()
  */
  */
 function hook_xmlsitemap_context_info_alter(&$info) {
 function hook_xmlsitemap_context_info_alter(&$info) {
   $info['vocabulary']['label'] = t('Site vocabularies');
   $info['vocabulary']['label'] = t('Site vocabularies');
@@ -230,7 +254,11 @@ function hook_xmlsitemap_element_alter(array &$element, array $link, $sitemap) {
  * Alter the attributes used for the root element of the XML sitemap.
  * Alter the attributes used for the root element of the XML sitemap.
  *
  *
  * For example add an xmlns:video attribute:
  * For example add an xmlns:video attribute:
- * <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
+ *
+ * @code
+ * <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
+ *   xmlns:video="https://www.google.com/schemas/sitemap-video/1.1">
+ * @endcode
  *
  *
  * @param array $attributes
  * @param array $attributes
  *   An associative array of attributes to use in the root element of an XML
  *   An associative array of attributes to use in the root element of an XML
@@ -238,14 +266,14 @@ function hook_xmlsitemap_element_alter(array &$element, array $link, $sitemap) {
  * @param object $sitemap
  * @param object $sitemap
  *   The sitemap that is currently being generated.
  *   The sitemap that is currently being generated.
  */
  */
-function hook_xmlsitemap_root_attributes_alter(&$attributes, $sitemap) {
-  $attributes['xmlns:video'] = 'http://www.google.com/schemas/sitemap-video/1.1';
+function hook_xmlsitemap_root_attributes_alter(array &$attributes, $sitemap) {
+  $attributes['xmlns:video'] = 'https://www.google.com/schemas/sitemap-video/1.1';
 }
 }
 
 
 /**
 /**
  * Alter the query selecting data from {xmlsitemap} during sitemap generation.
  * Alter the query selecting data from {xmlsitemap} during sitemap generation.
  *
  *
- * @param $query
+ * @param QueryAlterableInterface $query
  *   A Query object describing the composite parts of a SQL query.
  *   A Query object describing the composite parts of a SQL query.
  *
  *
  * @see hook_query_TAG_alter()
  * @see hook_query_TAG_alter()
@@ -277,11 +305,13 @@ function hook_xmlsitemap_sitemap_operations() {
  * This hook is invoked from xmlsitemap_sitemap_delete_multiple() after the XML
  * This hook is invoked from xmlsitemap_sitemap_delete_multiple() after the XML
  * sitemap has been removed from the table in the database.
  * sitemap has been removed from the table in the database.
  *
  *
- * @param $sitemap
+ * @param object $sitemap
  *   The XML sitemap object that was deleted.
  *   The XML sitemap object that was deleted.
  */
  */
 function hook_xmlsitemap_sitemap_delete(stdClass $sitemap) {
 function hook_xmlsitemap_sitemap_delete(stdClass $sitemap) {
-  db_query("DELETE FROM {mytable} WHERE smid = '%s'", $sitemap->smid);
+  db_delete('mytable')
+    ->condition('smid', $sitemap->smid, '=')
+    ->execute();
 }
 }
 
 
 /**
 /**

+ 14 - 4
sites/all/modules/xmlsitemap/xmlsitemap.drush.inc

@@ -7,10 +7,16 @@
  * @ingroup xmlsitemap
  * @ingroup xmlsitemap
  */
  */
 
 
+/**
+ * The default batch limit.
+ */
+define('XMLSITEMAP_BATCH_LIMIT', 100);
+
 /**
 /**
  * Implements hook_drush_command().
  * Implements hook_drush_command().
  */
  */
 function xmlsitemap_drush_command() {
 function xmlsitemap_drush_command() {
+
   $items['xmlsitemap-regenerate'] = array(
   $items['xmlsitemap-regenerate'] = array(
     'description' => 'Regenerate the XML sitemap files.',
     'description' => 'Regenerate the XML sitemap files.',
     'callback' => 'drush_xmlsitemap_regenerate',
     'callback' => 'drush_xmlsitemap_regenerate',
@@ -29,7 +35,7 @@ function xmlsitemap_drush_command() {
     'callback' => 'drush_xmlsitemap_index',
     'callback' => 'drush_xmlsitemap_index',
     'drupal dependencies' => array('xmlsitemap'),
     'drupal dependencies' => array('xmlsitemap'),
     'options' => array(
     'options' => array(
-      'limit' => 'The limit of links of each type to process. Default value: ' . variable_get('xmlsitemap_batch_limit', 100),
+      'limit' => 'The limit of links of each type to process. Default value: ' . variable_get('xmlsitemap_batch_limit', XMLSITEMAP_BATCH_LIMIT),
     ),
     ),
   );
   );
   $items['xmlsitemap-queue-rebuild'] = array(
   $items['xmlsitemap-queue-rebuild'] = array(
@@ -93,7 +99,7 @@ function drush_xmlsitemap_rebuild() {
  * Process un-indexed XML sitemap links.
  * Process un-indexed XML sitemap links.
  */
  */
 function drush_xmlsitemap_index() {
 function drush_xmlsitemap_index() {
-  $limit = (int) drush_get_option('limit', variable_get('xmlsitemap_batch_limit', 100));
+  $limit = (int) drush_get_option('limit', variable_get('xmlsitemap_batch_limit', XMLSITEMAP_BATCH_LIMIT));
   $count_before = db_query("SELECT COUNT(id) FROM {xmlsitemap}")->fetchField();
   $count_before = db_query("SELECT COUNT(id) FROM {xmlsitemap}")->fetchField();
 
 
   module_invoke_all('xmlsitemap_index_links', $limit);
   module_invoke_all('xmlsitemap_index_links', $limit);
@@ -129,7 +135,7 @@ function drush_xmlsitemap_queue_rebuild() {
 
 
   $link_count = 0;
   $link_count = 0;
   $chunk_count = 0;
   $chunk_count = 0;
-  $chunk_size = (int) drush_get_option('limit', variable_get('xmlsitemap_batch_limit', 100));
+  $chunk_size = (int) drush_get_option('limit', variable_get('xmlsitemap_batch_limit', XMLSITEMAP_BATCH_LIMIT));
 
 
   // @todo Figure out how to re-use this code with xmlsitemap_rebuild_batch_fetch()
   // @todo Figure out how to re-use this code with xmlsitemap_rebuild_batch_fetch()
   foreach ($types as $type) {
   foreach ($types as $type) {
@@ -162,7 +168,11 @@ function drush_xmlsitemap_queue_rebuild() {
   }
   }
 
 
   if ($link_count) {
   if ($link_count) {
-    drush_log(dt('Queued @link_count links for rebuild processing in the xmlsitemap_link_process (in @chunk_count chunks of up to @chunk_size links each).', array('@link_count' => $link_count, '@chunk_count' => $chunk_count, '@chunk_size' => $chunk_size)), 'success');
+    drush_log(dt('Queued @link_count links for rebuild processing in the xmlsitemap_link_process (in @chunk_count chunks of up to @chunk_size links each).', array(
+      '@link_count' => $link_count,
+      '@chunk_count' => $chunk_count,
+      '@chunk_size' => $chunk_size,
+    )), 'success');
   }
   }
   else {
   else {
     drush_log(dt('No links to queue for rebuild processing.'), 'ok');
     drush_log(dt('No links to queue for rebuild processing.'), 'ok');

+ 57 - 24
sites/all/modules/xmlsitemap/xmlsitemap.generate.inc

@@ -14,9 +14,9 @@
  * at once so that only one database query is executed instead of several or
  * at once so that only one database query is executed instead of several or
  * possibly thousands during sitemap generation.
  * possibly thousands during sitemap generation.
  *
  *
- * @param $path
+ * @param string $path
  *   An internal Drupal path.
  *   An internal Drupal path.
- * @param $language
+ * @param string $language
  *   A language code to use when looking up the paths.
  *   A language code to use when looking up the paths.
  */
  */
 function xmlsitemap_get_path_alias($path, $language) {
 function xmlsitemap_get_path_alias($path, $language) {
@@ -70,13 +70,16 @@ function _xmlsitemap_regenerate_before() {
 
 
   if (variable_get('xmlsitemap_developer_mode', 0)) {
   if (variable_get('xmlsitemap_developer_mode', 0)) {
     watchdog('xmlsitemap', 'Starting XML sitemap generation. Memory usage: @memory-peak.', array(
     watchdog('xmlsitemap', 'Starting XML sitemap generation. Memory usage: @memory-peak.', array(
-        '@memory-peak' => format_size(memory_get_peak_usage(TRUE)),
-      ),
+      '@memory-peak' => format_size(memory_get_peak_usage(TRUE)),
+    ),
       WATCHDOG_DEBUG
       WATCHDOG_DEBUG
     );
     );
   }
   }
 }
 }
 
 
+/**
+ * Get Memory Usage.
+ */
 function _xmlsitemap_get_memory_usage($start = FALSE) {
 function _xmlsitemap_get_memory_usage($start = FALSE) {
   static $memory_start;
   static $memory_start;
   $current = memory_get_peak_usage(TRUE);
   $current = memory_get_peak_usage(TRUE);
@@ -113,7 +116,7 @@ function _xmlsitemap_get_optimal_memory_limit() {
 /**
 /**
  * Calculate the optimal memory level for sitemap generation.
  * Calculate the optimal memory level for sitemap generation.
  *
  *
- * @param $new_limit
+ * @param string $new_limit
  *   An optional PHP memory limit in bytes. If not provided, the value of
  *   An optional PHP memory limit in bytes. If not provided, the value of
  *   _xmlsitemap_get_optimal_memory_limit() will be used.
  *   _xmlsitemap_get_optimal_memory_limit() will be used.
  */
  */
@@ -132,9 +135,9 @@ function _xmlsitemap_set_memory_limit($new_limit = NULL) {
 /**
 /**
  * Generate one page (chunk) of the sitemap.
  * Generate one page (chunk) of the sitemap.
  *
  *
- * @param $sitemap
+ * @param object $sitemap
  *   An unserialized data array for an XML sitemap.
  *   An unserialized data array for an XML sitemap.
- * @param $page
+ * @param string $page
  *   An integer of the specific page of the sitemap to generate.
  *   An integer of the specific page of the sitemap to generate.
  */
  */
 function xmlsitemap_generate_page(stdClass $sitemap, $page) {
 function xmlsitemap_generate_page(stdClass $sitemap, $page) {
@@ -147,20 +150,27 @@ function xmlsitemap_generate_page(stdClass $sitemap, $page) {
   catch (Exception $e) {
   catch (Exception $e) {
     watchdog_exception('xmlsitemap', $e);
     watchdog_exception('xmlsitemap', $e);
     throw $e;
     throw $e;
-    return FALSE;
   }
   }
 
 
   return $writer->getSitemapElementCount();
   return $writer->getSitemapElementCount();
 }
 }
 
 
+/**
+ * Generate chunk.
+ */
 function xmlsitemap_generate_chunk(stdClass $sitemap, XMLSitemapWriter $writer, $chunk) {
 function xmlsitemap_generate_chunk(stdClass $sitemap, XMLSitemapWriter $writer, $chunk) {
-  $output_elements = drupal_map_assoc(variable_get('xmlsitemap_output_elements', array('lastmod', 'changefreq', 'priority')));
+  global $base_url;
+  $output_elements = drupal_map_assoc(variable_get('xmlsitemap_output_elements', array(
+    'lastmod',
+    'changefreq',
+    'priority',
+  )));
   $lastmod_format = variable_get('xmlsitemap_lastmod_format', XMLSITEMAP_LASTMOD_MEDIUM);
   $lastmod_format = variable_get('xmlsitemap_lastmod_format', XMLSITEMAP_LASTMOD_MEDIUM);
 
 
   $url_options = $sitemap->uri['options'];
   $url_options = $sitemap->uri['options'];
   $url_options += array(
   $url_options += array(
     'absolute' => TRUE,
     'absolute' => TRUE,
-    'base_url' => variable_get('xmlsitemap_base_url', $GLOBALS['base_url']),
+    'base_url' => variable_get('xmlsitemap_base_url', $base_url),
     'language' => language_default(),
     'language' => language_default(),
     'alias' => variable_get('xmlsitemap_prefetch_aliases', TRUE),
     'alias' => variable_get('xmlsitemap_prefetch_aliases', TRUE),
   );
   );
@@ -169,7 +179,19 @@ function xmlsitemap_generate_chunk(stdClass $sitemap, XMLSitemapWriter $writer,
   $link_count = 0;
   $link_count = 0;
 
 
   $query = db_select('xmlsitemap', 'x');
   $query = db_select('xmlsitemap', 'x');
-  $query->fields('x', array('id', 'type', 'subtype', 'loc', 'lastmod', 'changefreq', 'changecount', 'priority', 'language', 'access', 'status'));
+  $query->fields('x', array(
+    'id',
+    'type',
+    'subtype',
+    'loc',
+    'lastmod',
+    'changefreq',
+    'changecount',
+    'priority',
+    'language',
+    'access',
+    'status',
+  ));
   $query->condition('x.access', 1);
   $query->condition('x.access', 1);
   $query->condition('x.status', 1);
   $query->condition('x.status', 1);
   $query->orderBy('x.language', 'DESC');
   $query->orderBy('x.language', 'DESC');
@@ -184,6 +206,9 @@ function xmlsitemap_generate_chunk(stdClass $sitemap, XMLSitemapWriter $writer,
 
 
   while ($link = $links->fetchAssoc()) {
   while ($link = $links->fetchAssoc()) {
     $link['language'] = $link['language'] != LANGUAGE_NONE ? xmlsitemap_language_load($link['language']) : $url_options['language'];
     $link['language'] = $link['language'] != LANGUAGE_NONE ? xmlsitemap_language_load($link['language']) : $url_options['language'];
+    $parsed_url = drupal_parse_url($link['loc']);
+    // Remove query or fragment.
+    $link['loc'] = $parsed_url['path'];
     if ($url_options['alias']) {
     if ($url_options['alias']) {
       $link['loc'] = xmlsitemap_get_path_alias($link['loc'], $link['language']->language);
       $link['loc'] = xmlsitemap_get_path_alias($link['loc'], $link['language']->language);
     }
     }
@@ -191,6 +216,8 @@ function xmlsitemap_generate_chunk(stdClass $sitemap, XMLSitemapWriter $writer,
       'language' => $link['language'],
       'language' => $link['language'],
       'xmlsitemap_link' => $link,
       'xmlsitemap_link' => $link,
       'xmlsitemap_sitemap' => $sitemap,
       'xmlsitemap_sitemap' => $sitemap,
+      'query' => $parsed_url['query'],
+      'fragment' => $parsed_url['fragment'],
     );
     );
     // @todo Add a separate hook_xmlsitemap_link_url_alter() here?
     // @todo Add a separate hook_xmlsitemap_link_url_alter() here?
     $link_url = url($link['loc'], $link_options + $url_options);
     $link_url = url($link['loc'], $link_options + $url_options);
@@ -241,7 +268,7 @@ function xmlsitemap_generate_chunk(stdClass $sitemap, XMLSitemapWriter $writer,
 /**
 /**
  * Generate the index sitemap.
  * Generate the index sitemap.
  *
  *
- * @param $sitemap
+ * @param object $sitemap
  *   An unserialized data array for an XML sitemap.
  *   An unserialized data array for an XML sitemap.
  */
  */
 function xmlsitemap_generate_index(stdClass $sitemap) {
 function xmlsitemap_generate_index(stdClass $sitemap) {
@@ -254,18 +281,17 @@ function xmlsitemap_generate_index(stdClass $sitemap) {
   catch (Exception $e) {
   catch (Exception $e) {
     watchdog_exception('xmlsitemap', $e);
     watchdog_exception('xmlsitemap', $e);
     throw $e;
     throw $e;
-    return FALSE;
   }
   }
 
 
   return $writer->getSitemapElementCount();
   return $writer->getSitemapElementCount();
 }
 }
 
 
-// BATCH OPERATIONS ------------------------------------------------------------
-
 /**
 /**
+ * BATCH OPERATIONS -----------------------------------------------------------.
+ *
  * Batch information callback for regenerating the sitemap files.
  * Batch information callback for regenerating the sitemap files.
  *
  *
- * @param $smids
+ * @param array $smids
  *   An optional array of XML sitemap IDs. If not provided, it will load all
  *   An optional array of XML sitemap IDs. If not provided, it will load all
  *   existing XML sitemaps.
  *   existing XML sitemaps.
  */
  */
@@ -273,11 +299,8 @@ function xmlsitemap_regenerate_batch(array $smids = array()) {
   if (empty($smids)) {
   if (empty($smids)) {
     $smids = db_query("SELECT smid FROM {xmlsitemap_sitemap}")->fetchCol();
     $smids = db_query("SELECT smid FROM {xmlsitemap_sitemap}")->fetchCol();
   }
   }
-
-  //$t = get_t();
   $batch = array(
   $batch = array(
     'operations' => array(),
     'operations' => array(),
-    //'error_message' => $t('An error has occurred.'),
     'finished' => 'xmlsitemap_regenerate_batch_finished',
     'finished' => 'xmlsitemap_regenerate_batch_finished',
     'title' => t('Regenerating Sitemap'),
     'title' => t('Regenerating Sitemap'),
     'file' => drupal_get_path('module', 'xmlsitemap') . '/xmlsitemap.generate.inc',
     'file' => drupal_get_path('module', 'xmlsitemap') . '/xmlsitemap.generate.inc',
@@ -361,7 +384,7 @@ function xmlsitemap_regenerate_batch_generate_index($smid, array &$context) {
 function xmlsitemap_regenerate_batch_finished($success, $results, $operations, $elapsed) {
 function xmlsitemap_regenerate_batch_finished($success, $results, $operations, $elapsed) {
   if ($success && !variable_get('xmlsitemap_regenerate_needed', FALSE)) {
   if ($success && !variable_get('xmlsitemap_regenerate_needed', FALSE)) {
     variable_set('xmlsitemap_generated_last', REQUEST_TIME);
     variable_set('xmlsitemap_generated_last', REQUEST_TIME);
-    //drupal_set_message(t('The sitemaps were regenerated.'));
+    // drupal_set_message(t('The sitemaps were regenerated.'));
     // Show a watchdog message that the sitemap was regenerated.
     // Show a watchdog message that the sitemap was regenerated.
     watchdog('xmlsitemap',
     watchdog('xmlsitemap',
       'Finished XML sitemap generation in @elapsed. Memory usage: @memory-peak.',
       'Finished XML sitemap generation in @elapsed. Memory usage: @memory-peak.',
@@ -371,6 +394,7 @@ function xmlsitemap_regenerate_batch_finished($success, $results, $operations, $
       ),
       ),
       WATCHDOG_NOTICE
       WATCHDOG_NOTICE
     );
     );
+    module_invoke_all('xmlsitemap_regenerate_finished');
   }
   }
   else {
   else {
     drupal_set_message(t('The sitemaps were not successfully regenerated.'), 'error');
     drupal_set_message(t('The sitemaps were not successfully regenerated.'), 'error');
@@ -392,7 +416,9 @@ function xmlsitemap_rebuild_batch(array $entities, $save_custom = FALSE) {
   $batch['operations'][] = array('xmlsitemap_batch_variable_set', array(array('xmlsitemap_rebuild_needed' => TRUE)));
   $batch['operations'][] = array('xmlsitemap_batch_variable_set', array(array('xmlsitemap_rebuild_needed' => TRUE)));
 
 
   // Purge any links first.
   // Purge any links first.
-  $batch['operations'][] = array('xmlsitemap_rebuild_batch_clear', array($entities, (bool) $save_custom));
+  $batch['operations'][] = array('xmlsitemap_rebuild_batch_clear',
+    array($entities, (bool) $save_custom),
+  );
 
 
   // Fetch all the sitemap links and save them to the {xmlsitemap} table.
   // Fetch all the sitemap links and save them to the {xmlsitemap} table.
   foreach ($entities as $entity) {
   foreach ($entities as $entity) {
@@ -467,8 +493,7 @@ function xmlsitemap_rebuild_batch_fetch($entity, &$context) {
 
 
   // PostgreSQL cannot have the ORDERED BY in the count query.
   // PostgreSQL cannot have the ORDERED BY in the count query.
   $query->entityOrderBy('entity_id');
   $query->entityOrderBy('entity_id');
-
-  $limit = 20; //variable_get('xmlsitemap_batch_limit', 100)
+  $limit = 20;
   $query->range(0, $limit);
   $query->range(0, $limit);
 
 
   $result = $query->execute();
   $result = $query->execute();
@@ -477,7 +502,12 @@ function xmlsitemap_rebuild_batch_fetch($entity, &$context) {
   $info['xmlsitemap']['process callback']($ids);
   $info['xmlsitemap']['process callback']($ids);
   $context['sandbox']['last_id'] = end($ids);
   $context['sandbox']['last_id'] = end($ids);
   $context['sandbox']['progress'] += count($ids);
   $context['sandbox']['progress'] += count($ids);
-  $context['message'] = t('Now processing %entity @last_id (@progress of @count).', array('%entity' => $entity, '@last_id' => $context['sandbox']['last_id'], '@progress' => $context['sandbox']['progress'], '@count' => $context['sandbox']['max']));
+  $context['message'] = t('Now processing %entity @last_id (@progress of @count).', array(
+    '%entity' => $entity,
+    '@last_id' => $context['sandbox']['last_id'],
+    '@progress' => $context['sandbox']['progress'],
+    '@count' => $context['sandbox']['max'],
+  ));
 
 
   if ($context['sandbox']['progress'] >= $context['sandbox']['max']) {
   if ($context['sandbox']['progress'] >= $context['sandbox']['max']) {
     $context['finished'] = 1;
     $context['finished'] = 1;
@@ -499,6 +529,9 @@ function xmlsitemap_rebuild_batch_finished($success, $results, $operations, $ela
   }
   }
 }
 }
 
 
+/**
+ * Get Rebuildable link types.
+ */
 function xmlsitemap_get_rebuildable_link_types() {
 function xmlsitemap_get_rebuildable_link_types() {
   $rebuild_types = array();
   $rebuild_types = array();
   $entities = xmlsitemap_get_link_info();
   $entities = xmlsitemap_get_link_info();

File diff suppressed because it is too large
+ 5 - 5
sites/all/modules/xmlsitemap/xmlsitemap.inc


+ 4 - 11
sites/all/modules/xmlsitemap/xmlsitemap.info

@@ -2,21 +2,14 @@ name = XML sitemap
 description = Creates an XML sitemap conforming to the <a href="http://sitemaps.org/">sitemaps.org protocol</a>.
 description = Creates an XML sitemap conforming to the <a href="http://sitemaps.org/">sitemaps.org protocol</a>.
 package = XML sitemap
 package = XML sitemap
 core = 7.x
 core = 7.x
-files[] = xmlsitemap.module
-files[] = xmlsitemap.inc
-files[] = xmlsitemap.admin.inc
-files[] = xmlsitemap.drush.inc
-files[] = xmlsitemap.generate.inc
 files[] = xmlsitemap.xmlsitemap.inc
 files[] = xmlsitemap.xmlsitemap.inc
-files[] = xmlsitemap.pages.inc
-files[] = xmlsitemap.install
 files[] = xmlsitemap.test
 files[] = xmlsitemap.test
 recommends[] = robotstxt
 recommends[] = robotstxt
 configure = admin/config/search/xmlsitemap
 configure = admin/config/search/xmlsitemap
+test_dependencies[] = robotstxt:robotstxt
 
 
-; Information added by Drupal.org packaging script on 2016-05-25
-version = "7.x-2.3"
+; Information added by Drupal.org packaging script on 2018-10-09
+version = "7.x-2.6"
 core = "7.x"
 core = "7.x"
 project = "xmlsitemap"
 project = "xmlsitemap"
-datestamp = "1464191061"
-
+datestamp = "1539120486"

+ 24 - 8
sites/all/modules/xmlsitemap/xmlsitemap.install

@@ -25,7 +25,7 @@ function xmlsitemap_requirements($phase) {
       'value' => $t('Disabled'),
       'value' => $t('Disabled'),
       'severity' => REQUIREMENT_ERROR,
       'severity' => REQUIREMENT_ERROR,
       'description' => $t("The XML sitemap module requires you to enable the PHP extensions in the following list (see the <a href=\"@xmlsitemap_requirements\">module's system requirements page</a> for more information):", array(
       'description' => $t("The XML sitemap module requires you to enable the PHP extensions in the following list (see the <a href=\"@xmlsitemap_requirements\">module's system requirements page</a> for more information):", array(
-        '@xmlsitemap_requirements' => 'http://drupal.org/documentation/modules/xmlsitemap/requirements',
+        '@xmlsitemap_requirements' => 'https://www.drupal.org/documentation/modules/xmlsitemap/requirements',
       )) . theme('item_list', array('items' => $missing_extensions)),
       )) . theme('item_list', array('items' => $missing_extensions)),
     );
     );
   }
   }
@@ -50,7 +50,7 @@ function xmlsitemap_requirements($phase) {
     if (!xmlsitemap_check_directory()) {
     if (!xmlsitemap_check_directory()) {
       $requirements['xmlsitemap_directory']['value'] = $t('Not found or not writable');
       $requirements['xmlsitemap_directory']['value'] = $t('Not found or not writable');
       $requirements['xmlsitemap_directory']['severity'] = REQUIREMENT_ERROR;
       $requirements['xmlsitemap_directory']['severity'] = REQUIREMENT_ERROR;
-      $requirements['xmlsitemap_directory']['description'] = $t('The directory %directory was not found or is not writable by the server. See <a href="@docpage">@docpage</a> for more information.', array('%directory' => xmlsitemap_get_directory(), '@docpage' => 'http://drupal.org/node/34025'));
+      $requirements['xmlsitemap_directory']['description'] = $t('The directory %directory was not found or is not writable by the server. See <a href="@docpage">@docpage</a> for more information.', array('%directory' => xmlsitemap_get_directory(), '@docpage' => 'https://www.drupal.org/node/244924'));
     }
     }
     else {
     else {
       $directories = xmlsitemap_check_all_directories();
       $directories = xmlsitemap_check_all_directories();
@@ -62,7 +62,11 @@ function xmlsitemap_requirements($phase) {
       if (!empty($directories)) {
       if (!empty($directories)) {
         $requirements['xmlsitemap_directory']['value'] = $t('Not found or not writable');
         $requirements['xmlsitemap_directory']['value'] = $t('Not found or not writable');
         $requirements['xmlsitemap_directory']['severity'] = REQUIREMENT_ERROR;
         $requirements['xmlsitemap_directory']['severity'] = REQUIREMENT_ERROR;
-        $requirements['xmlsitemap_directory']['description'] = $t('The following directories were not found or are not writable by the server. See <a href="@docpage">@docpage</a> for more information. !directories', array('!directories' => theme('item_list', array('items' => array_keys($directories))), '@docpage' => 'http://drupal.org/node/34025'));
+        $requirements['xmlsitemap_directory']['description'] = $t('The following directories were not found or are not writable by the server. See <a href="@docpage">@docpage</a> for more information. !directories', array(
+          '!directories' => theme('item_list', array(
+            'items' => array_keys($directories),
+          )), '@docpage' => 'https://www.drupal.org/node/244924',
+        ));
       }
       }
     }
     }
 
 
@@ -111,7 +115,10 @@ function xmlsitemap_requirements($phase) {
     $generated_ago = REQUEST_TIME - $generated_last;
     $generated_ago = REQUEST_TIME - $generated_last;
     $requirements['xmlsitemap_generated'] = array(
     $requirements['xmlsitemap_generated'] = array(
       'title' => $t('XML sitemap'),
       'title' => $t('XML sitemap'),
-      'value' => $generated_last ? $t('Last attempted generation on !date (!interval ago).', array('!date' => format_date($generated_last, 'small'), '!interval' => format_interval($generated_ago))) : $t('Cached files have not been generated yet.'),
+      'value' => $generated_last ? $t('Last attempted generation on !date (!interval ago).', array(
+        '!date' => format_date($generated_last, 'small'),
+        '!interval' => format_interval($generated_ago),
+      )) : $t('Cached files have not been generated yet.'),
       'severity' => REQUIREMENT_OK,
       'severity' => REQUIREMENT_OK,
     );
     );
     if (variable_get('xmlsitemap_rebuild_needed', FALSE) && _xmlsitemap_rebuild_form_access()) {
     if (variable_get('xmlsitemap_rebuild_needed', FALSE) && _xmlsitemap_rebuild_form_access()) {
@@ -214,8 +221,8 @@ function xmlsitemap_schema() {
         'type' => 'float',
         'type' => 'float',
         'default' => NULL,
         'default' => NULL,
         // @todo Convert this field to non-nullable.
         // @todo Convert this field to non-nullable.
-        //'default' => 0.5,
-        //'not null' => NULL,
+        // 'default' => 0.5,
+        // 'not null' => NULL,
       ),
       ),
       'priority_override' => array(
       'priority_override' => array(
         'description' => 'A boolean that if TRUE means that the priority field has been overridden from its default value.',
         'description' => 'A boolean that if TRUE means that the priority field has been overridden from its default value.',
@@ -286,13 +293,15 @@ function xmlsitemap_schema() {
         'not null' => TRUE,
         'not null' => TRUE,
         'default' => 0,
         'default' => 0,
       ),
       ),
-      //'queued' => array(
+      // @codingStandardsIgnoreStart
+      // 'queued' => array(
       //  'type' => 'int',
       //  'type' => 'int',
       //  'unsigned' => TRUE,
       //  'unsigned' => TRUE,
       //  'not null' => TRUE,
       //  'not null' => TRUE,
       //  'default' => 0,
       //  'default' => 0,
       //  'description' => 'Time when this sitemap was queued for regeneration, 0 if not queued.',
       //  'description' => 'Time when this sitemap was queued for regeneration, 0 if not queued.',
-      //),
+      // ),.
+      // @codingStandardsIgnoreEnd
     ),
     ),
     'primary key' => array('smid'),
     'primary key' => array('smid'),
   );
   );
@@ -463,6 +472,8 @@ function xmlsitemap_update_6202() {
 }
 }
 
 
 /**
 /**
+ * Implements hook_update_N().
+ *
  * Convert the xmlsitemap_max_filesize variable to a max_filesize column
  * Convert the xmlsitemap_max_filesize variable to a max_filesize column
  * per-sitemap.
  * per-sitemap.
  */
  */
@@ -539,6 +550,8 @@ function xmlsitemap_update_7201() {
 }
 }
 
 
 /**
 /**
+ * Implements hook_update_N().
+ *
  * Convert the xmlsitemap_max_filesize variable to a max_filesize column
  * Convert the xmlsitemap_max_filesize variable to a max_filesize column
  * per-sitemap.
  * per-sitemap.
  */
  */
@@ -554,6 +567,9 @@ function xmlsitemap_update_7203() {
   _xmlsitemap_sitemap_rehash_all();
   _xmlsitemap_sitemap_rehash_all();
 }
 }
 
 
+/**
+ * Rehash all.
+ */
 function _xmlsitemap_sitemap_rehash_all() {
 function _xmlsitemap_sitemap_rehash_all() {
   // Reload the schema cache and reprocess all sitemap hashes into smids.
   // Reload the schema cache and reprocess all sitemap hashes into smids.
   drupal_load('module', 'xmlsitemap');
   drupal_load('module', 'xmlsitemap');

+ 217 - 83
sites/all/modules/xmlsitemap/xmlsitemap.module

@@ -1,6 +1,7 @@
 <?php
 <?php
 
 
 /**
 /**
+ * @file
  * @defgroup xmlsitemap XML sitemap
  * @defgroup xmlsitemap XML sitemap
  */
  */
 
 
@@ -19,11 +20,16 @@ define('XMLSITEMAP_MAX_SITEMAP_LINKS', 50000);
  */
  */
 define('XMLSITEMAP_MAX_SITEMAP_FILESIZE', 10485760);
 define('XMLSITEMAP_MAX_SITEMAP_FILESIZE', 10485760);
 
 
-define('XMLSITEMAP_FREQUENCY_YEARLY', 31449600); // 60 * 60 * 24 * 7 * 52
-define('XMLSITEMAP_FREQUENCY_MONTHLY', 2419200); // 60 * 60 * 24 * 7 * 4
-define('XMLSITEMAP_FREQUENCY_WEEKLY', 604800); // 60 * 60 * 24 * 7
-define('XMLSITEMAP_FREQUENCY_DAILY', 86400); // 60 * 60 * 24
-define('XMLSITEMAP_FREQUENCY_HOURLY', 3600); // 60 * 60
+// 60 * 60 * 24 * 7 * 52.
+define('XMLSITEMAP_FREQUENCY_YEARLY', 31449600);
+// 60 * 60 * 24 * 7 * 4.
+define('XMLSITEMAP_FREQUENCY_MONTHLY', 2419200);
+// 60 * 60 * 24 * 7.
+define('XMLSITEMAP_FREQUENCY_WEEKLY', 604800);
+// 60 * 60 * 24.
+define('XMLSITEMAP_FREQUENCY_DAILY', 86400);
+// 60 * 60.
+define('XMLSITEMAP_FREQUENCY_HOURLY', 3600);
 define('XMLSITEMAP_FREQUENCY_ALWAYS', 60);
 define('XMLSITEMAP_FREQUENCY_ALWAYS', 60);
 
 
 /**
 /**
@@ -97,10 +103,13 @@ function xmlsitemap_help($path, $arg) {
     case 'admin/config/search/xmlsitemap/edit/%':
     case 'admin/config/search/xmlsitemap/edit/%':
     case 'admin/config/search/xmlsitemap/delete/%':
     case 'admin/config/search/xmlsitemap/delete/%':
       return;
       return;
+
     case 'admin/help#xmlsitemap':
     case 'admin/help#xmlsitemap':
       break;
       break;
+
     case 'admin/config/search/xmlsitemap':
     case 'admin/config/search/xmlsitemap':
       break;
       break;
+
     case 'admin/config/search/xmlsitemap/rebuild':
     case 'admin/config/search/xmlsitemap/rebuild':
       $output .= '<p>' . t("This action rebuilds your site's XML sitemap and regenerates the cached files, and may be a lengthy process. If you just installed XML sitemap, this can be helpful to import all your site's content into the sitemap. Otherwise, this should only be used in emergencies.") . '</p>';
       $output .= '<p>' . t("This action rebuilds your site's XML sitemap and regenerates the cached files, and may be a lengthy process. If you just installed XML sitemap, this can be helpful to import all your site's content into the sitemap. Otherwise, this should only be used in emergencies.") . '</p>';
   }
   }
@@ -122,7 +131,11 @@ function xmlsitemap_help($path, $arg) {
  */
  */
 function xmlsitemap_permission() {
 function xmlsitemap_permission() {
   $permissions['administer xmlsitemap'] = array(
   $permissions['administer xmlsitemap'] = array(
-    'title' => t('Administer XML sitemap settings.'),
+    'title' => t('Administer XML sitemap settings'),
+  );
+  $permissions['use xmlsitemap'] = array(
+    'title' => t('Use XML sitemap'),
+    'description' => t('Users can change individually the default XML Sitemap settings.'),
   );
   );
   return $permissions;
   return $permissions;
 }
 }
@@ -281,6 +294,7 @@ function xmlsitemap_robotstxt() {
  * Internal default variables for xmlsitemap_var().
  * Internal default variables for xmlsitemap_var().
  */
  */
 function xmlsitemap_variables() {
 function xmlsitemap_variables() {
+  global $base_url;
   return array(
   return array(
     'xmlsitemap_rebuild_needed' => FALSE,
     'xmlsitemap_rebuild_needed' => FALSE,
     'xmlsitemap_regenerate_needed' => FALSE,
     'xmlsitemap_regenerate_needed' => FALSE,
@@ -291,7 +305,7 @@ function xmlsitemap_variables() {
     'xmlsitemap_chunk_size' => 'auto',
     'xmlsitemap_chunk_size' => 'auto',
     'xmlsitemap_batch_limit' => 100,
     'xmlsitemap_batch_limit' => 100,
     'xmlsitemap_path' => 'xmlsitemap',
     'xmlsitemap_path' => 'xmlsitemap',
-    'xmlsitemap_base_url' => $GLOBALS['base_url'],
+    'xmlsitemap_base_url' => $base_url,
     'xmlsitemap_developer_mode' => 0,
     'xmlsitemap_developer_mode' => 0,
     'xmlsitemap_frontpage_priority' => 1.0,
     'xmlsitemap_frontpage_priority' => 1.0,
     'xmlsitemap_frontpage_changefreq' => XMLSITEMAP_FREQUENCY_DAILY,
     'xmlsitemap_frontpage_changefreq' => XMLSITEMAP_FREQUENCY_DAILY,
@@ -338,13 +352,16 @@ function xmlsitemap_var($name, $default = NULL) {
 /**
 /**
  * Load an XML sitemap array from the database.
  * Load an XML sitemap array from the database.
  *
  *
- * @param $smid
+ * @param array $smid
  *   An XML sitemap ID.
  *   An XML sitemap ID.
  *
  *
- * @return
+ * @return object
  *   The XML sitemap object.
  *   The XML sitemap object.
+ *
+ * @codingStandardsIgnoreStart
  */
  */
 function xmlsitemap_sitemap_load($smid) {
 function xmlsitemap_sitemap_load($smid) {
+  // @codingStandardsIgnoreEnd
   $sitemap = xmlsitemap_sitemap_load_multiple(array($smid));
   $sitemap = xmlsitemap_sitemap_load_multiple(array($smid));
   return $sitemap ? reset($sitemap) : FALSE;
   return $sitemap ? reset($sitemap) : FALSE;
 }
 }
@@ -352,15 +369,18 @@ function xmlsitemap_sitemap_load($smid) {
 /**
 /**
  * Load multiple XML sitemaps from the database.
  * Load multiple XML sitemaps from the database.
  *
  *
- * @param $smids
+ * @param array $smids
  *   An array of XML sitemap IDs, or FALSE to load all XML sitemaps.
  *   An array of XML sitemap IDs, or FALSE to load all XML sitemaps.
- * @param $conditions
+ * @param array $conditions
  *   An array of conditions in the form 'field' => $value.
  *   An array of conditions in the form 'field' => $value.
  *
  *
- * @return
+ * @return array
  *   An array of XML sitemap objects.
  *   An array of XML sitemap objects.
+ *
+ * @codingStandardsIgnoreStart
  */
  */
 function xmlsitemap_sitemap_load_multiple($smids = array(), array $conditions = array()) {
 function xmlsitemap_sitemap_load_multiple($smids = array(), array $conditions = array()) {
+  // @codingStandardsIgnoreEnd
   if ($smids !== FALSE) {
   if ($smids !== FALSE) {
     $conditions['smid'] = $smids;
     $conditions['smid'] = $smids;
   }
   }
@@ -383,7 +403,7 @@ function xmlsitemap_sitemap_load_multiple($smids = array(), array $conditions =
 /**
 /**
  * Load an XML sitemap array from the database based on its context.
  * Load an XML sitemap array from the database based on its context.
  *
  *
- * @param $context
+ * @param array $context
  *   An optional XML sitemap context array to use to find the correct XML
  *   An optional XML sitemap context array to use to find the correct XML
  *   sitemap. If not provided, the current site's context will be used.
  *   sitemap. If not provided, the current site's context will be used.
  *
  *
@@ -401,7 +421,7 @@ function xmlsitemap_sitemap_load_by_context(array $context = NULL) {
 /**
 /**
  * Save changes to an XML sitemap or add a new XML sitemap.
  * Save changes to an XML sitemap or add a new XML sitemap.
  *
  *
- * @param $sitemap
+ * @param object $sitemap
  *   The XML sitemap array to be saved. If $sitemap->smid is omitted, a new
  *   The XML sitemap array to be saved. If $sitemap->smid is omitted, a new
  *   XML sitemap will be added.
  *   XML sitemap will be added.
  *
  *
@@ -450,25 +470,28 @@ function xmlsitemap_sitemap_save(stdClass $sitemap) {
 /**
 /**
  * Delete an XML sitemap.
  * Delete an XML sitemap.
  *
  *
- * @param $smid
+ * @param array $smid
  *   An XML sitemap ID.
  *   An XML sitemap ID.
+ *
+ * @codingStandardsIgnoreStart
  */
  */
 function xmlsitemap_sitemap_delete($smid) {
 function xmlsitemap_sitemap_delete($smid) {
+  // @codingStandardsIgnoreEnd
   xmlsitemap_sitemap_delete_multiple(array($smid));
   xmlsitemap_sitemap_delete_multiple(array($smid));
 }
 }
 
 
 /**
 /**
  * Delete multiple XML sitemaps.
  * Delete multiple XML sitemaps.
  *
  *
- * @param $smids
+ * @param array $smids
  *   An array of XML sitemap IDs.
  *   An array of XML sitemap IDs.
  */
  */
 function xmlsitemap_sitemap_delete_multiple(array $smids) {
 function xmlsitemap_sitemap_delete_multiple(array $smids) {
   if (!empty($smids)) {
   if (!empty($smids)) {
     $sitemaps = xmlsitemap_sitemap_load_multiple($smids);
     $sitemaps = xmlsitemap_sitemap_load_multiple($smids);
     db_delete('xmlsitemap_sitemap')
     db_delete('xmlsitemap_sitemap')
-        ->condition('smid', $smids)
-        ->execute();
+      ->condition('smid', $smids)
+      ->execute();
 
 
     foreach ($sitemaps as $sitemap) {
     foreach ($sitemaps as $sitemap) {
       xmlsitemap_clear_directory($sitemap, TRUE);
       xmlsitemap_clear_directory($sitemap, TRUE);
@@ -480,9 +503,9 @@ function xmlsitemap_sitemap_delete_multiple(array $smids) {
 /**
 /**
  * Return the expected file path for a specific sitemap chunk.
  * Return the expected file path for a specific sitemap chunk.
  *
  *
- * @param $sitemap
+ * @param object $sitemap
  *   An XML sitemap array.
  *   An XML sitemap array.
- * @param $chunk
+ * @param string $chunk
  *   An optional specific chunk in the sitemap. Defaults to the index page.
  *   An optional specific chunk in the sitemap. Defaults to the index page.
  */
  */
 function xmlsitemap_sitemap_get_file(stdClass $sitemap, $chunk = 'index') {
 function xmlsitemap_sitemap_get_file(stdClass $sitemap, $chunk = 'index') {
@@ -492,7 +515,7 @@ function xmlsitemap_sitemap_get_file(stdClass $sitemap, $chunk = 'index') {
 /**
 /**
  * Find the maximum file size of all a sitemap's XML files.
  * Find the maximum file size of all a sitemap's XML files.
  *
  *
- * @param $sitemap
+ * @param object $sitemap
  *   The XML sitemap array.
  *   The XML sitemap array.
  */
  */
 function xmlsitemap_sitemap_get_max_filesize(stdClass $sitemap) {
 function xmlsitemap_sitemap_get_max_filesize(stdClass $sitemap) {
@@ -504,6 +527,9 @@ function xmlsitemap_sitemap_get_max_filesize(stdClass $sitemap) {
   return $sitemap->max_filesize;
   return $sitemap->max_filesize;
 }
 }
 
 
+/**
+ * Get context.
+ */
 function xmlsitemap_sitemap_get_context_hash(array &$context) {
 function xmlsitemap_sitemap_get_context_hash(array &$context) {
   asort($context);
   asort($context);
   return drupal_hash_base64(serialize($context));
   return drupal_hash_base64(serialize($context));
@@ -512,19 +538,21 @@ function xmlsitemap_sitemap_get_context_hash(array &$context) {
 /**
 /**
  * Returns the uri elements of an XML sitemap.
  * Returns the uri elements of an XML sitemap.
  *
  *
- * @param $sitemap
+ * @param object $sitemap
  *   An unserialized data array for an XML sitemap.
  *   An unserialized data array for an XML sitemap.
- * @return
+ *
+ * @return array
  *   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 XML sitemap, and matching the signature of url().
  *   the XML sitemap, and matching the signature of url().
  */
  */
 function xmlsitemap_sitemap_uri(stdClass $sitemap) {
 function xmlsitemap_sitemap_uri(stdClass $sitemap) {
+  global $base_url;
   $uri['path'] = 'sitemap.xml';
   $uri['path'] = 'sitemap.xml';
   $uri['options'] = module_invoke_all('xmlsitemap_context_url_options', $sitemap->context);
   $uri['options'] = module_invoke_all('xmlsitemap_context_url_options', $sitemap->context);
   drupal_alter('xmlsitemap_context_url_options', $uri['options'], $sitemap->context);
   drupal_alter('xmlsitemap_context_url_options', $uri['options'], $sitemap->context);
   $uri['options'] += array(
   $uri['options'] += array(
     'absolute' => TRUE,
     'absolute' => TRUE,
-    'base_url' => variable_get('xmlsitemap_base_url', $GLOBALS['base_url']),
+    'base_url' => variable_get('xmlsitemap_base_url', $base_url),
   );
   );
   return $uri;
   return $uri;
 }
 }
@@ -532,11 +560,12 @@ function xmlsitemap_sitemap_uri(stdClass $sitemap) {
 /**
 /**
  * Load a specific sitemap link from the database.
  * Load a specific sitemap link from the database.
  *
  *
- * @param $entity_type
+ * @param string $entity_type
  *   A string with the entity type.
  *   A string with the entity type.
- * @param $entity_id
+ * @param int $entity_id
  *   An integer with the entity ID.
  *   An integer with the entity ID.
- * @return
+ *
+ * @return array
  *   A sitemap link (array) or FALSE if the conditions were not found.
  *   A sitemap link (array) or FALSE if the conditions were not found.
  */
  */
 function xmlsitemap_link_load($entity_type, $entity_id) {
 function xmlsitemap_link_load($entity_type, $entity_id) {
@@ -547,10 +576,11 @@ function xmlsitemap_link_load($entity_type, $entity_id) {
 /**
 /**
  * Load sitemap links from the database.
  * Load sitemap links from the database.
  *
  *
- * @param $conditions
+ * @param array $conditions
  *   An array of conditions on the {xmlsitemap} table in the form
  *   An array of conditions on the {xmlsitemap} table in the form
  *   'field' => $value.
  *   'field' => $value.
- * @return
+ *
+ * @return array
  *   An array of sitemap link arrays.
  *   An array of sitemap link arrays.
  */
  */
 function xmlsitemap_link_load_multiple(array $conditions = array()) {
 function xmlsitemap_link_load_multiple(array $conditions = array()) {
@@ -566,6 +596,26 @@ function xmlsitemap_link_load_multiple(array $conditions = array()) {
   return $links;
   return $links;
 }
 }
 
 
+/**
+ * Presave a sitemap link.
+ *
+ * @param array $link
+ *   An array with a sitemap link.
+ * @param array $context
+ *   An optional context array containing data related to the link.
+ */
+function xmlsitemap_link_presave(array $link, array $context = array()) {
+  // Force link access to 0 in presave so that the link is saved with revoked
+  // access until the node permissions are checked in the cron.
+  $link['access'] = 0;
+
+  // Allow other modules to alter the sitemap link presave.
+  drupal_alter('xmlsitemap_link_presave', $link, $context);
+
+  // Save or update a sitemap link which will be overwritten in Drupal cron job.
+  xmlsitemap_link_save($link, $context);
+}
+
 /**
 /**
  * Saves or updates a sitemap link.
  * Saves or updates a sitemap link.
  *
  *
@@ -596,10 +646,16 @@ function xmlsitemap_link_save(array $link, array $context = array()) {
   // Temporary validation checks.
   // Temporary validation checks.
   // @todo Remove in final?
   // @todo Remove in final?
   if ($link['priority'] < 0 || $link['priority'] > 1) {
   if ($link['priority'] < 0 || $link['priority'] > 1) {
-    trigger_error(t('Invalid sitemap link priority %priority.<br />@link', array('%priority' => $link['priority'], '@link' => var_export($link, TRUE))), E_USER_ERROR);
+    trigger_error(t('Invalid sitemap link priority %priority.<br />@link', array(
+      '%priority' => $link['priority'],
+      '@link' => var_export($link, TRUE),
+    )), E_USER_ERROR);
   }
   }
   if ($link['changecount'] < 0) {
   if ($link['changecount'] < 0) {
-    trigger_error(t('Negative changecount value. Please report this to <a href="@516928">@516928</a>.<br />@link', array('@516928' => 'http://drupal.org/node/516928', '@link' => var_export($link, TRUE))), E_USER_ERROR);
+    trigger_error(t('Negative changecount value. Please report this to <a href="@516928">@516928</a>.<br />@link', array(
+      '@516928' => 'https://www.drupal.org/node/516928',
+      '@link' => var_export($link, TRUE),
+    )), E_USER_ERROR);
     $link['changecount'] = 0;
     $link['changecount'] = 0;
   }
   }
 
 
@@ -629,14 +685,18 @@ function xmlsitemap_link_save(array $link, array $context = array()) {
  * If visible links are updated, this will automatically set the regenerate
  * If visible links are updated, this will automatically set the regenerate
  * needed flag to TRUE.
  * needed flag to TRUE.
  *
  *
- * @param $updates
+ * @param array $updates
  *   An array of values to update fields to, keyed by field name.
  *   An array of values to update fields to, keyed by field name.
- * @param $conditions
+ * @param array $conditions
  *   An array of values to match keyed by field.
  *   An array of values to match keyed by field.
- * @return
+ *
+ * @return int
  *   The number of links that were updated.
  *   The number of links that were updated.
+ *
+ * @codingStandardsIgnoreStart
  */
  */
 function xmlsitemap_link_update_multiple($updates = array(), $conditions = array(), $check_flag = TRUE) {
 function xmlsitemap_link_update_multiple($updates = array(), $conditions = array(), $check_flag = TRUE) {
+  // @codingStandardsIgnoreEnd
   // If we are going to modify a visible sitemap link, we will need to set
   // If we are going to modify a visible sitemap link, we will need to set
   // the regenerate needed flag.
   // the regenerate needed flag.
   if ($check_flag && !variable_get('xmlsitemap_regenerate_needed', FALSE)) {
   if ($check_flag && !variable_get('xmlsitemap_regenerate_needed', FALSE)) {
@@ -659,11 +719,12 @@ function xmlsitemap_link_update_multiple($updates = array(), $conditions = array
  * If a visible sitemap link was deleted, this will automatically set the
  * If a visible sitemap link was deleted, this will automatically set the
  * regenerate needed flag.
  * regenerate needed flag.
  *
  *
- * @param $entity_type
+ * @param string $entity_type
  *   A string with the entity type.
  *   A string with the entity type.
- * @param $entity_id
+ * @param int $entity_id
  *   An integer with the entity ID.
  *   An integer with the entity ID.
- * @return
+ *
+ * @return int
  *   The number of links that were deleted.
  *   The number of links that were deleted.
  */
  */
 function xmlsitemap_link_delete($entity_type, $entity_id) {
 function xmlsitemap_link_delete($entity_type, $entity_id) {
@@ -677,17 +738,18 @@ function xmlsitemap_link_delete($entity_type, $entity_id) {
  * If visible sitemap links were deleted, this will automatically set the
  * If visible sitemap links were deleted, this will automatically set the
  * regenerate needed flag.
  * regenerate needed flag.
  *
  *
- * @param $conditions
+ * @param array $conditions
  *   An array of conditions on the {xmlsitemap} table in the form
  *   An array of conditions on the {xmlsitemap} table in the form
  *   'field' => $value.
  *   'field' => $value.
- * @return
+ *
+ * @return int
  *   The number of links that were deleted.
  *   The number of links that were deleted.
  */
  */
 function xmlsitemap_link_delete_multiple(array $conditions) {
 function xmlsitemap_link_delete_multiple(array $conditions) {
   // Because this function is called from sub-module uninstall hooks, we have
   // Because this function is called from sub-module uninstall hooks, we have
   // to manually check if the table exists since it could have been removed
   // to manually check if the table exists since it could have been removed
   // in xmlsitemap_uninstall().
   // in xmlsitemap_uninstall().
-  // @todo Remove this check when http://drupal.org/node/151452 is fixed.
+  // @todo Remove this check when https://www.drupal.org/node/151452 is fixed.
   if (!db_table_exists('xmlsitemap')) {
   if (!db_table_exists('xmlsitemap')) {
     return FALSE;
     return FALSE;
   }
   }
@@ -709,12 +771,13 @@ function xmlsitemap_link_delete_multiple(array $conditions) {
 /**
 /**
  * Check if there is a visible sitemap link given a certain set of conditions.
  * Check if there is a visible sitemap link given a certain set of conditions.
  *
  *
- * @param $conditions
+ * @param array $conditions
  *   An array of values to match keyed by field.
  *   An array of values to match keyed by field.
- * @param $flag
+ * @param string $flag
  *   An optional boolean that if TRUE, will set the regenerate needed flag if
  *   An optional boolean that if TRUE, will set the regenerate needed flag if
  *   there is a match. Defaults to FALSE.
  *   there is a match. Defaults to FALSE.
- * @return
+ *
+ * @return bool
  *   TRUE if there is a visible link, or FALSE otherwise.
  *   TRUE if there is a visible link, or FALSE otherwise.
  */
  */
 function _xmlsitemap_check_changed_links(array $conditions = array(), array $updates = array(), $flag = FALSE) {
 function _xmlsitemap_check_changed_links(array $conditions = array(), array $updates = array(), $flag = FALSE) {
@@ -740,19 +803,23 @@ function _xmlsitemap_check_changed_links(array $conditions = array(), array $upd
 /**
 /**
  * Check if there is sitemap link is changed from the existing data.
  * Check if there is sitemap link is changed from the existing data.
  *
  *
- * @param $link
+ * @param array $link
  *   An array of the sitemap link.
  *   An array of the sitemap link.
- * @param $original_link
+ * @param array $original_link
  *   An optional array of the existing data. This should only contain the
  *   An optional array of the existing data. This should only contain the
  *   fields necessary for comparison. If not provided the existing data will be
  *   fields necessary for comparison. If not provided the existing data will be
  *   loaded from the database.
  *   loaded from the database.
- * @param $flag
+ * @param bool $flag
  *   An optional boolean that if TRUE, will set the regenerate needed flag if
  *   An optional boolean that if TRUE, will set the regenerate needed flag if
  *   there is a match. Defaults to FALSE.
  *   there is a match. Defaults to FALSE.
- * @return
+ *
+ * @return bool
  *   TRUE if the link is changed, or FALSE otherwise.
  *   TRUE if the link is changed, or FALSE otherwise.
+ *
+ * @codingStandardsIgnoreStart
  */
  */
 function _xmlsitemap_check_changed_link(array $link, $original_link = NULL, $flag = FALSE) {
 function _xmlsitemap_check_changed_link(array $link, $original_link = NULL, $flag = FALSE) {
+  // @codingStandardsIgnoreEnd
   $changed = FALSE;
   $changed = FALSE;
 
 
   if ($original_link === NULL) {
   if ($original_link === NULL) {
@@ -772,7 +839,7 @@ function _xmlsitemap_check_changed_link(array $link, $original_link = NULL, $fla
       $changed = TRUE;
       $changed = TRUE;
     }
     }
     elseif ($original_link['access'] && $original_link['status'] && array_diff_assoc($original_link, $link)) {
     elseif ($original_link['access'] && $original_link['status'] && array_diff_assoc($original_link, $link)) {
-      // Changing a visible link
+      // Changing a visible link.
       $changed = TRUE;
       $changed = TRUE;
     }
     }
   }
   }
@@ -787,7 +854,6 @@ function _xmlsitemap_check_changed_link(array $link, $original_link = NULL, $fla
 /**
 /**
  * @} End of "defgroup xmlsitemap_api"
  * @} End of "defgroup xmlsitemap_api"
  */
  */
-
 function xmlsitemap_get_directory(stdClass $sitemap = NULL) {
 function xmlsitemap_get_directory(stdClass $sitemap = NULL) {
   $directory = &drupal_static(__FUNCTION__);
   $directory = &drupal_static(__FUNCTION__);
 
 
@@ -815,6 +881,9 @@ function xmlsitemap_check_directory(stdClass $sitemap = NULL) {
   return $result;
   return $result;
 }
 }
 
 
+/**
+ * Check all directories.
+ */
 function xmlsitemap_check_all_directories() {
 function xmlsitemap_check_all_directories() {
   $directories = array();
   $directories = array();
 
 
@@ -837,6 +906,9 @@ function xmlsitemap_check_all_directories() {
   return $directories;
   return $directories;
 }
 }
 
 
+/**
+ * Clear Directory.
+ */
 function xmlsitemap_clear_directory(stdClass $sitemap = NULL, $delete = FALSE) {
 function xmlsitemap_clear_directory(stdClass $sitemap = NULL, $delete = FALSE) {
   $directory = xmlsitemap_get_directory($sitemap);
   $directory = xmlsitemap_get_directory($sitemap);
   return _xmlsitemap_delete_recursive($directory, $delete);
   return _xmlsitemap_delete_recursive($directory, $delete);
@@ -845,14 +917,14 @@ function xmlsitemap_clear_directory(stdClass $sitemap = NULL, $delete = FALSE) {
 /**
 /**
  * Move a directory to a new location.
  * Move a directory to a new location.
  *
  *
- * @param $old_dir
+ * @param string $old_dir
  *   A string specifying the filepath or URI of the original directory.
  *   A string specifying the filepath or URI of the original directory.
- * @param $new_dir
+ * @param string $new_dir
  *   A string specifying the filepath or URI of the new directory.
  *   A string specifying the filepath or URI of the new directory.
- * @param $replace
+ * @param string $replace
  *   Replace behavior when the destination file already exists.
  *   Replace behavior when the destination file already exists.
  *
  *
- * @return
+ * @return bool
  *   TRUE if the directory was moved successfully. FALSE otherwise.
  *   TRUE if the directory was moved successfully. FALSE otherwise.
  */
  */
 function xmlsitemap_directory_move($old_dir, $new_dir, $replace = FILE_EXISTS_REPLACE) {
 function xmlsitemap_directory_move($old_dir, $new_dir, $replace = FILE_EXISTS_REPLACE) {
@@ -882,9 +954,9 @@ function xmlsitemap_directory_move($old_dir, $new_dir, $replace = FILE_EXISTS_RE
  *
  *
  * Note that this only deletes visible files with write permission.
  * Note that this only deletes visible files with write permission.
  *
  *
- * @param $path
+ * @param string $path
  *   A filepath relative to the Drupal root directory.
  *   A filepath relative to the Drupal root directory.
- * @param $delete_root
+ * @param bool $delete_root
  *   A boolean if TRUE will delete the $path directory afterwards.
  *   A boolean if TRUE will delete the $path directory afterwards.
  */
  */
 function _xmlsitemap_delete_recursive($path, $delete_root = FALSE) {
 function _xmlsitemap_delete_recursive($path, $delete_root = FALSE) {
@@ -908,10 +980,10 @@ function _xmlsitemap_delete_recursive($path, $delete_root = FALSE) {
 /**
 /**
  * Returns information about supported sitemap link types.
  * Returns information about supported sitemap link types.
  *
  *
- * @param $type
+ * @param string $type
  *   (optional) The link type to return information for. If omitted,
  *   (optional) The link type to return information for. If omitted,
  *   information for all link types is returned.
  *   information for all link types is returned.
- * @param $reset
+ * @param bool $reset
  *   (optional) Boolean whether to reset the static cache and do nothing. Only
  *   (optional) Boolean whether to reset the static cache and do nothing. Only
  *   used for tests.
  *   used for tests.
  *
  *
@@ -943,7 +1015,7 @@ function xmlsitemap_get_link_info($type = NULL, $reset = FALSE) {
         foreach ($info['bundles'] as $bundle_key => $bundle) {
         foreach ($info['bundles'] as $bundle_key => $bundle) {
           if (!isset($bundle['xmlsitemap'])) {
           if (!isset($bundle['xmlsitemap'])) {
             // Remove any un-supported entity bundles.
             // Remove any un-supported entity bundles.
-            //unset($link_info[$key]['bundles'][$bundle_key]);
+            // unset($link_info[$key]['bundles'][$bundle_key]);.
           }
           }
         }
         }
       }
       }
@@ -979,19 +1051,25 @@ function xmlsitemap_get_link_info($type = NULL, $reset = FALSE) {
   return $link_info;
   return $link_info;
 }
 }
 
 
+/**
+ * Enabled Bundles.
+ */
 function xmlsitemap_get_link_type_enabled_bundles($entity_type) {
 function xmlsitemap_get_link_type_enabled_bundles($entity_type) {
   $bundles = array();
   $bundles = array();
   $info = xmlsitemap_get_link_info($entity_type);
   $info = xmlsitemap_get_link_info($entity_type);
   foreach ($info['bundles'] as $bundle => $bundle_info) {
   foreach ($info['bundles'] as $bundle => $bundle_info) {
     $settings = xmlsitemap_link_bundle_load($entity_type, $bundle);
     $settings = xmlsitemap_link_bundle_load($entity_type, $bundle);
     if (!empty($settings['status'])) {
     if (!empty($settings['status'])) {
-    //if (!empty($bundle_info['xmlsitemap']['status'])) {
+      // If (!empty($bundle_info['xmlsitemap']['status'])) {.
       $bundles[] = $bundle;
       $bundles[] = $bundle;
     }
     }
   }
   }
   return $bundles;
   return $bundles;
 }
 }
 
 
+/**
+ * Indexed Status.
+ */
 function xmlsitemap_get_link_type_indexed_status($entity_type, $bundle = '') {
 function xmlsitemap_get_link_type_indexed_status($entity_type, $bundle = '') {
   $info = xmlsitemap_get_link_info($entity_type);
   $info = xmlsitemap_get_link_info($entity_type);
 
 
@@ -1002,7 +1080,7 @@ function xmlsitemap_get_link_type_indexed_status($entity_type, $bundle = '') {
   $total->entityCondition('entity_type', $entity_type);
   $total->entityCondition('entity_type', $entity_type);
   $total->entityCondition('bundle', $bundle);
   $total->entityCondition('bundle', $bundle);
   $total->entityCondition('entity_id', 0, '>');
   $total->entityCondition('entity_id', 0, '>');
-  //$total->addTag('xmlsitemap_link_bundle_access');
+  // $total->addTag('xmlsitemap_link_bundle_access');.
   $total->addTag('xmlsitemap_link_indexed_status');
   $total->addTag('xmlsitemap_link_indexed_status');
   $total->addMetaData('entity', $entity_type);
   $total->addMetaData('entity', $entity_type);
   $total->addMetaData('bundle', $bundle);
   $total->addMetaData('bundle', $bundle);
@@ -1016,7 +1094,7 @@ function xmlsitemap_get_link_type_indexed_status($entity_type, $bundle = '') {
 /**
 /**
  * Implements hook_entity_query_alter().
  * Implements hook_entity_query_alter().
  *
  *
- * @todo Remove when http://drupal.org/node/1054168 is fixed.
+ * @todo Remove when https://www.drupal.org/node/1054168 is fixed.
  */
  */
 function xmlsitemap_entity_query_alter($query) {
 function xmlsitemap_entity_query_alter($query) {
   $conditions = &$query->entityConditions;
   $conditions = &$query->entityConditions;
@@ -1027,22 +1105,38 @@ function xmlsitemap_entity_query_alter($query) {
   }
   }
 }
 }
 
 
+/**
+ * Budle Settings.
+ */
 function xmlsitemap_link_bundle_settings_save($entity, $bundle, array $settings, $update_links = TRUE) {
 function xmlsitemap_link_bundle_settings_save($entity, $bundle, array $settings, $update_links = TRUE) {
   if ($update_links) {
   if ($update_links) {
     $old_settings = xmlsitemap_link_bundle_load($entity, $bundle);
     $old_settings = xmlsitemap_link_bundle_load($entity, $bundle);
     if ($settings['status'] != $old_settings['status']) {
     if ($settings['status'] != $old_settings['status']) {
-      xmlsitemap_link_update_multiple(array('status' => $settings['status']), array('type' => $entity, 'subtype' => $bundle, 'status_override' => 0));
+      xmlsitemap_link_update_multiple(array('status' => $settings['status']), array(
+        'type' => $entity,
+        'subtype' => $bundle,
+        'status_override' => 0,
+      ));
     }
     }
     if ($settings['priority'] != $old_settings['priority']) {
     if ($settings['priority'] != $old_settings['priority']) {
-      xmlsitemap_link_update_multiple(array('priority' => $settings['priority']), array('type' => $entity, 'subtype' => $bundle, 'priority_override' => 0));
+      xmlsitemap_link_update_multiple(array(
+        'priority' => $settings['priority'],
+      ), array(
+        'type' => $entity,
+        'subtype' => $bundle,
+        'priority_override' => 0,
+      ));
     }
     }
   }
   }
 
 
   variable_set("xmlsitemap_settings_{$entity}_{$bundle}", $settings);
   variable_set("xmlsitemap_settings_{$entity}_{$bundle}", $settings);
   cache_clear_all('xmlsitemap:link_info:', 'cache', TRUE);
   cache_clear_all('xmlsitemap:link_info:', 'cache', TRUE);
-  //xmlsitemap_get_link_info(NULL, TRUE);
+  // xmlsitemap_get_link_info(NULL, TRUE);.
 }
 }
 
 
+/**
+ * Bundle Rename.
+ */
 function xmlsitemap_link_bundle_rename($entity, $bundle_old, $bundle_new) {
 function xmlsitemap_link_bundle_rename($entity, $bundle_old, $bundle_new) {
   if ($bundle_old != $bundle_new) {
   if ($bundle_old != $bundle_new) {
     $settings = xmlsitemap_link_bundle_load($entity, $bundle_old);
     $settings = xmlsitemap_link_bundle_load($entity, $bundle_old);
@@ -1070,6 +1164,9 @@ function xmlsitemap_link_type_rename($entity_old, $entity_new, $bundles = NULL)
   xmlsitemap_get_link_info(NULL, TRUE);
   xmlsitemap_get_link_info(NULL, TRUE);
 }
 }
 
 
+/**
+ * Bundle Load.
+ */
 function xmlsitemap_link_bundle_load($entity, $bundle, $load_bundle_info = TRUE) {
 function xmlsitemap_link_bundle_load($entity, $bundle, $load_bundle_info = TRUE) {
   $info = array(
   $info = array(
     'entity' => $entity,
     'entity' => $entity,
@@ -1089,15 +1186,21 @@ function xmlsitemap_link_bundle_load($entity, $bundle, $load_bundle_info = TRUE)
   return $info;
   return $info;
 }
 }
 
 
+/**
+ * Bundle Delete.
+ */
 function xmlsitemap_link_bundle_delete($entity, $bundle, $delete_links = TRUE) {
 function xmlsitemap_link_bundle_delete($entity, $bundle, $delete_links = TRUE) {
   variable_del("xmlsitemap_settings_{$entity}_{$bundle}");
   variable_del("xmlsitemap_settings_{$entity}_{$bundle}");
   if ($delete_links) {
   if ($delete_links) {
     xmlsitemap_link_delete_multiple(array('type' => $entity, 'subtype' => $bundle));
     xmlsitemap_link_delete_multiple(array('type' => $entity, 'subtype' => $bundle));
   }
   }
   cache_clear_all('xmlsitemap:link_info:', 'cache', TRUE);
   cache_clear_all('xmlsitemap:link_info:', 'cache', TRUE);
-  //xmlsitemap_get_link_info(NULL, TRUE);
+  // xmlsitemap_get_link_info(NULL, TRUE);.
 }
 }
 
 
+/**
+ * Bundle Access.
+ */
 function xmlsitemap_link_bundle_access($entity, $bundle = NULL) {
 function xmlsitemap_link_bundle_access($entity, $bundle = NULL) {
   if (is_array($entity) && !isset($bundle)) {
   if (is_array($entity) && !isset($bundle)) {
     $bundle = $entity;
     $bundle = $entity;
@@ -1122,6 +1225,9 @@ function xmlsitemap_link_bundle_access($entity, $bundle = NULL) {
   return FALSE;
   return FALSE;
 }
 }
 
 
+/**
+ * Get Bundle.
+ */
 function xmlsitemap_get_bundle_path($entity, $bundle) {
 function xmlsitemap_get_bundle_path($entity, $bundle) {
   $info = xmlsitemap_get_link_info($entity);
   $info = xmlsitemap_get_link_info($entity);
 
 
@@ -1153,9 +1259,10 @@ function xmlsitemap_field_attach_delete_bundle($entity_type, $bundle, $instances
 /**
 /**
  * Determine the frequency of updates to a link.
  * Determine the frequency of updates to a link.
  *
  *
- * @param $interval
+ * @param string $interval
  *   An interval value in seconds.
  *   An interval value in seconds.
- * @return
+ *
+ * @return string
  *   A string representing the update frequency according to the sitemaps.org
  *   A string representing the update frequency according to the sitemaps.org
  *   protocol.
  *   protocol.
  */
  */
@@ -1203,9 +1310,10 @@ function xmlsitemap_get_link_count($reset = FALSE) {
  * calculate the appropriate value. Use this function instead of @code
  * calculate the appropriate value. Use this function instead of @code
  * xmlsitemap_var('chunk_size') @endcode when the actual value is needed.
  * xmlsitemap_var('chunk_size') @endcode when the actual value is needed.
  *
  *
- * @param $reset
+ * @param bool $reset
  *   A boolean to reset the saved, static result. Defaults to FALSE.
  *   A boolean to reset the saved, static result. Defaults to FALSE.
- * @return
+ *
+ * @return int
  *   An integer with the number of links in each sitemap page.
  *   An integer with the number of links in each sitemap page.
  */
  */
 function xmlsitemap_get_chunk_size($reset = FALSE) {
 function xmlsitemap_get_chunk_size($reset = FALSE) {
@@ -1213,7 +1321,8 @@ function xmlsitemap_get_chunk_size($reset = FALSE) {
   if (!isset($size) || $reset) {
   if (!isset($size) || $reset) {
     $size = xmlsitemap_var('chunk_size');
     $size = xmlsitemap_var('chunk_size');
     if ($size === 'auto') {
     if ($size === 'auto') {
-      $count = max(xmlsitemap_get_link_count($reset), 1); // Prevent divide by zero.
+      // Prevent divide by zero.
+      $count = max(xmlsitemap_get_link_count($reset), 1);
       $size = min(ceil($count / 10000) * 5000, XMLSITEMAP_MAX_SITEMAP_LINKS);
       $size = min(ceil($count / 10000) * 5000, XMLSITEMAP_MAX_SITEMAP_LINKS);
     }
     }
   }
   }
@@ -1223,10 +1332,13 @@ function xmlsitemap_get_chunk_size($reset = FALSE) {
 /**
 /**
  * Recalculate the changefreq of a sitemap link.
  * Recalculate the changefreq of a sitemap link.
  *
  *
- * @param $link
+ * @param array $link
  *   A sitemap link array.
  *   A sitemap link array.
+ *
+ * @codingStandardsIgnoreStart
  */
  */
 function xmlsitemap_recalculate_changefreq(&$link) {
 function xmlsitemap_recalculate_changefreq(&$link) {
+  // @codingStandardsIgnoreEnd
   $link['changefreq'] = round((($link['changefreq'] * $link['changecount']) + (REQUEST_TIME - $link['lastmod'])) / ($link['changecount'] + 1));
   $link['changefreq'] = round((($link['changefreq'] * $link['changecount']) + (REQUEST_TIME - $link['lastmod'])) / ($link['changecount'] + 1));
   $link['changecount']++;
   $link['changecount']++;
   $link['lastmod'] = REQUEST_TIME;
   $link['lastmod'] = REQUEST_TIME;
@@ -1235,12 +1347,16 @@ function xmlsitemap_recalculate_changefreq(&$link) {
 /**
 /**
  * Calculates the average interval between UNIX timestamps.
  * Calculates the average interval between UNIX timestamps.
  *
  *
- * @param $timestamps
+ * @param array $timestamps
  *   An array of UNIX timestamp integers.
  *   An array of UNIX timestamp integers.
- * @return
+ *
+ * @return int
  *   An integer of the average interval.
  *   An integer of the average interval.
+ *
+ * @codingStandardsIgnoreStart
  */
  */
 function xmlsitemap_calculate_changefreq($timestamps) {
 function xmlsitemap_calculate_changefreq($timestamps) {
+  // @codingStandardsIgnoreEnd
   sort($timestamps);
   sort($timestamps);
   $count = count($timestamps) - 1;
   $count = count($timestamps) - 1;
   $diff = 0;
   $diff = 0;
@@ -1275,7 +1391,7 @@ function xmlsitemap_form_submit_flag_regenerate($form, $form_state) {
 /**
 /**
  * Set the current user stored in $GLOBALS['user'].
  * Set the current user stored in $GLOBALS['user'].
  *
  *
- * @todo Remove when http://drupal.org/node/287292 is fixed.
+ * @todo Remove when https://www.drupal.org/node/287292 is fixed.
  */
  */
 function xmlsitemap_switch_user($new_user = NULL) {
 function xmlsitemap_switch_user($new_user = NULL) {
   global $user;
   global $user;
@@ -1328,17 +1444,24 @@ function xmlsitemap_switch_user($new_user = NULL) {
 /**
 /**
  * Restore the user that was originally loaded.
  * Restore the user that was originally loaded.
  *
  *
- * @return
- *  Current user.
+ * @codingStandardsIgnoreLine
+ * @return object.
+ *   Current user.
  */
  */
 function xmlsitemap_restore_user() {
 function xmlsitemap_restore_user() {
   return xmlsitemap_switch_user();
   return xmlsitemap_switch_user();
 }
 }
 
 
+/**
+ * Form Link.
+ */
 function xmlsitemap_process_form_link_options($form, &$form_state) {
 function xmlsitemap_process_form_link_options($form, &$form_state) {
   $link = &$form_state['values']['xmlsitemap'];
   $link = &$form_state['values']['xmlsitemap'];
   $fields = array('status' => XMLSITEMAP_STATUS_DEFAULT, 'priority' => XMLSITEMAP_PRIORITY_DEFAULT);
   $fields = array('status' => XMLSITEMAP_STATUS_DEFAULT, 'priority' => XMLSITEMAP_PRIORITY_DEFAULT);
 
 
+  if (empty($link)) {
+    return;
+  }
   foreach ($fields as $field => $default) {
   foreach ($fields as $field => $default) {
     if ($link[$field] === 'default') {
     if ($link[$field] === 'default') {
       $link[$field] = isset($link[$field . '_default']) ? $link[$field . '_default'] : $default;
       $link[$field] = isset($link[$field . '_default']) ? $link[$field . '_default'] : $default;
@@ -1350,6 +1473,9 @@ function xmlsitemap_process_form_link_options($form, &$form_state) {
   }
   }
 }
 }
 
 
+/**
+ * Link bundle settings form submit.
+ */
 function xmlsitemap_link_bundle_settings_form_submit($form, &$form_state) {
 function xmlsitemap_link_bundle_settings_form_submit($form, &$form_state) {
   $entity = $form['xmlsitemap']['#entity'];
   $entity = $form['xmlsitemap']['#entity'];
   $bundle = $form['xmlsitemap']['#bundle'];
   $bundle = $form['xmlsitemap']['#bundle'];
@@ -1376,11 +1502,13 @@ function xmlsitemap_link_bundle_settings_form_submit($form, &$form_state) {
 
 
   // Unset the form values since we have already saved the bundle settings and
   // Unset the form values since we have already saved the bundle settings and
   // we don't want these values to get saved as variables in-case this form
   // we don't want these values to get saved as variables in-case this form
-  // also uses system_settings_form().
+  // Also uses system_settings_form().
   unset($form_state['values']['xmlsitemap']);
   unset($form_state['values']['xmlsitemap']);
 }
 }
 
 
 /**
 /**
+ * Get Freq.
+ *
  * @todo Document this function.
  * @todo Document this function.
  * @todo Make these translatable
  * @todo Make these translatable
  */
  */
@@ -1398,11 +1526,12 @@ function xmlsitemap_get_changefreq_options() {
 /**
 /**
  * Load a language object by its language code.
  * Load a language object by its language code.
  *
  *
- * @todo Remove when http://drupal.org/node/660736 is fixed in Drupal core.
+ * @todo Remove when https://www.drupal.org/node/660736 is fixed in Drupal core.
  *
  *
- * @param $language
+ * @param string $language
  *   A language code. If not provided the default language will be returned.
  *   A language code. If not provided the default language will be returned.
- * @return
+ *
+ * @return object
  *   A language object.
  *   A language object.
  */
  */
 function xmlsitemap_language_load($language = LANGUAGE_NONE) {
 function xmlsitemap_language_load($language = LANGUAGE_NONE) {
@@ -1420,7 +1549,6 @@ function xmlsitemap_language_load($language = LANGUAGE_NONE) {
  * @defgroup xmlsitemap_context_api XML sitemap API for sitemap contexts.
  * @defgroup xmlsitemap_context_api XML sitemap API for sitemap contexts.
  * @{
  * @{
  */
  */
-
 function xmlsitemap_get_context_info($context = NULL, $reset = FALSE) {
 function xmlsitemap_get_context_info($context = NULL, $reset = FALSE) {
   global $language;
   global $language;
   $info = &drupal_static(__FUNCTION__);
   $info = &drupal_static(__FUNCTION__);
@@ -1462,6 +1590,9 @@ function xmlsitemap_get_current_context() {
   return $context;
   return $context;
 }
 }
 
 
+/**
+ * Context summary.
+ */
 function _xmlsitemap_sitemap_context_summary(stdClass $sitemap, $context_key, array $context_info) {
 function _xmlsitemap_sitemap_context_summary(stdClass $sitemap, $context_key, array $context_info) {
   $context_value = isset($sitemap->context[$context_key]) ? $sitemap->context[$context_key] : NULL;
   $context_value = isset($sitemap->context[$context_key]) ? $sitemap->context[$context_key] : NULL;
 
 
@@ -1505,7 +1636,7 @@ function xmlsitemap_run_unprogressive_batch() {
   batch_set($batch);
   batch_set($batch);
 
 
   // We need to manually set the progressive variable again.
   // We need to manually set the progressive variable again.
-  // @todo Remove when http://drupal.org/node/638712 is fixed.
+  // @todo Remove when https://www.drupal.org/node/638712 is fixed.
   $batch =& batch_get();
   $batch =& batch_get();
   $batch['progressive'] = FALSE;
   $batch['progressive'] = FALSE;
 
 
@@ -1519,7 +1650,7 @@ function xmlsitemap_run_unprogressive_batch() {
 /**
 /**
  * Workaround for missing breadcrumbs on callback and action paths.
  * Workaround for missing breadcrumbs on callback and action paths.
  *
  *
- * @todo Remove when http://drupal.org/node/576290 is fixed.
+ * @todo Remove when https://www.drupal.org/node/576290 is fixed.
  */
  */
 function _xmlsitemap_set_breadcrumb($path = 'admin/config/search/xmlsitemap') {
 function _xmlsitemap_set_breadcrumb($path = 'admin/config/search/xmlsitemap') {
   $breadcrumb = array();
   $breadcrumb = array();
@@ -1533,6 +1664,9 @@ function _xmlsitemap_set_breadcrumb($path = 'admin/config/search/xmlsitemap') {
   drupal_set_breadcrumb($breadcrumb);
   drupal_set_breadcrumb($breadcrumb);
 }
 }
 
 
+/**
+ * Get operation link.
+ */
 function xmlsitemap_get_operation_link($url, $options = array()) {
 function xmlsitemap_get_operation_link($url, $options = array()) {
   static $destination;
   static $destination;
 
 

+ 6 - 4
sites/all/modules/xmlsitemap/xmlsitemap.pages.inc

@@ -74,14 +74,14 @@ function xmlsitemap_output_file($file, array $headers = array()) {
   $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : FALSE;
   $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : FALSE;
   if ($if_modified_since && $if_none_match && $if_none_match == $etag && $if_modified_since == $last_modified) {
   if ($if_modified_since && $if_none_match && $if_none_match == $etag && $if_modified_since == $last_modified) {
     header('HTTP/1.1 304 Not Modified');
     header('HTTP/1.1 304 Not Modified');
-    // All 304 responses must send an etag if the 200 response for the same object contained an etag
+    // All 304 responses must send an etag if the 200 response for the same
+    // object contained an etag.
     header('Etag: ' . $etag);
     header('Etag: ' . $etag);
     exit;
     exit;
   }
   }
 
 
   $headers += array(
   $headers += array(
     'Content-type' => 'text/xml; charset=utf-8',
     'Content-type' => 'text/xml; charset=utf-8',
-    //'Content-length' => filesize($file),
     'Last-modified' => $last_modified,
     'Last-modified' => $last_modified,
     'Etag' => $etag,
     'Etag' => $etag,
     'Expires' => gmdate(DATE_RFC1123, $mtime + variable_get('xmlsitemap_minimum_lifetime', 0)),
     'Expires' => gmdate(DATE_RFC1123, $mtime + variable_get('xmlsitemap_minimum_lifetime', 0)),
@@ -115,9 +115,11 @@ function xmlsitemap_file_transfer($uri, $headers) {
   // Transfer file in 16 KB chunks to save memory usage.
   // Transfer file in 16 KB chunks to save memory usage.
   if ($scheme && file_stream_wrapper_valid_scheme($scheme) && $fd = fopen($uri, 'rb')) {
   if ($scheme && file_stream_wrapper_valid_scheme($scheme) && $fd = fopen($uri, 'rb')) {
     while (!feof($fd)) {
     while (!feof($fd)) {
-      print fread($fd, 1024*16);
+      print fread($fd, 1024 * 16);
     }
     }
     fclose($fd);
     fclose($fd);
+    // Disable session manipulation if PHP transferred a file.
+    drupal_save_session(FALSE);
   }
   }
   else {
   else {
     drupal_not_found();
     drupal_not_found();
@@ -136,7 +138,7 @@ function xmlsitemap_output_xsl() {
   // Make sure the strings in the XSL content are translated properly.
   // Make sure the strings in the XSL content are translated properly.
   $replacements = array(
   $replacements = array(
     'Sitemap file' => t('Sitemap file'),
     'Sitemap file' => t('Sitemap file'),
-    'Generated by the <a href="http://drupal.org/project/xmlsitemap">Drupal XML sitemap module</a>.' => t('Generated by the <a href="@link-xmlsitemap">Drupal XML sitemap module</a>.', array('@link-xmlsitemap' => 'http://drupal.org/project/xmlsitemap')),
+    'Generated by the <a href="https://www.drupal.org/project/xmlsitemap">Drupal XML sitemap</a>.' => t('Generated by the <a href="@link-xmlsitemap">Drupal XML sitemap</a>.', array('@link-xmlsitemap' => 'https://www.drupal.org/project/xmlsitemap')),
     'Number of sitemaps in this index' => t('Number of sitemaps in this index'),
     'Number of sitemaps in this index' => t('Number of sitemaps in this index'),
     'Click on the table headers to change sorting.' => t('Click on the table headers to change sorting.'),
     'Click on the table headers to change sorting.' => t('Click on the table headers to change sorting.'),
     'Sitemap URL' => t('Sitemap URL'),
     'Sitemap URL' => t('Sitemap URL'),

+ 262 - 83
sites/all/modules/xmlsitemap/xmlsitemap.test

@@ -2,7 +2,7 @@
 
 
 /**
 /**
  * @file
  * @file
- * Unit tests for the xmlsitemap module.
+ * Unit tests for the xmlsitemap.
  *
  *
  * @ingroup xmlsitemap
  * @ingroup xmlsitemap
  */
  */
@@ -11,14 +11,30 @@
  * Helper test class with some added functions for testing.
  * Helper test class with some added functions for testing.
  */
  */
 class XMLSitemapTestHelper extends DrupalWebTestCase {
 class XMLSitemapTestHelper extends DrupalWebTestCase {
+
+  /**
+   * Admin User.
+   *
+   * @var string
+   *
+   * @codingStandardsIgnoreStart
+   */
   protected $admin_user;
   protected $admin_user;
 
 
-  function setUp($modules = array()) {
+  /**
+   * SetUp.
+   *
+   * @codingStandardsIgnoreEnd
+   */
+  public function setUp($modules = array()) {
     array_unshift($modules, 'xmlsitemap');
     array_unshift($modules, 'xmlsitemap');
     parent::setUp($modules);
     parent::setUp($modules);
   }
   }
 
 
-  function tearDown() {
+  /**
+   * Tear Down.
+   */
+  public function tearDown() {
     // Capture any (remaining) watchdog errors.
     // Capture any (remaining) watchdog errors.
     $this->assertNoWatchdogErrors();
     $this->assertNoWatchdogErrors();
 
 
@@ -28,12 +44,13 @@ class XMLSitemapTestHelper extends DrupalWebTestCase {
   /**
   /**
    * Assert the page does not respond with the specified response code.
    * Assert the page does not respond with the specified response code.
    *
    *
-   * @param $code
+   * @param string $code
    *   Response code. For example 200 is a successful page request. For a list
    *   Response code. For example 200 is a successful page request. For a list
    *   of all codes see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.
    *   of all codes see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.
-   * @param $message
+   * @param string $message
    *   Message to display.
    *   Message to display.
-   * @return
+   *
+   * @return string
    *   Assertion result.
    *   Assertion result.
    */
    */
   protected function assertNoResponse($code, $message = '') {
   protected function assertNoResponse($code, $message = '') {
@@ -45,7 +62,7 @@ class XMLSitemapTestHelper extends DrupalWebTestCase {
   /**
   /**
    * Check the files directory is created (massive fails if not done).
    * Check the files directory is created (massive fails if not done).
    *
    *
-   * @todo This can be removed when http://drupal.org/node/654752 is fixed.
+   * @todo This can be removed when https://www.drupal.org/node/654752 is fixed.
    */
    */
   protected function checkFilesDirectory() {
   protected function checkFilesDirectory() {
     if (!xmlsitemap_check_directory()) {
     if (!xmlsitemap_check_directory()) {
@@ -56,15 +73,16 @@ class XMLSitemapTestHelper extends DrupalWebTestCase {
   /**
   /**
    * Retrieves an XML sitemap.
    * Retrieves an XML sitemap.
    *
    *
-   * @param $context
+   * @param array $context
    *   An optional array of the XML sitemap's context.
    *   An optional array of the XML sitemap's context.
-   * @param $options
+   * @param array $options
    *   Options to be forwarded to url(). These values will be merged with, but
    *   Options to be forwarded to url(). These values will be merged with, but
    *   always override $sitemap->uri['options'].
    *   always override $sitemap->uri['options'].
-   * @param $headers
+   * @param array $headers
    *   An array containing additional HTTP request headers, each formatted as
    *   An array containing additional HTTP request headers, each formatted as
    *   "name: value".
    *   "name: value".
-   * @return
+   *
+   * @return string
    *   The retrieved HTML string, also available as $this->drupalGetContent()
    *   The retrieved HTML string, also available as $this->drupalGetContent()
    */
    */
   protected function drupalGetSitemap(array $context = array(), array $options = array(), array $headers = array()) {
   protected function drupalGetSitemap(array $context = array(), array $options = array(), array $headers = array()) {
@@ -85,6 +103,9 @@ class XMLSitemapTestHelper extends DrupalWebTestCase {
     $this->assertTrue(variable_get('xmlsitemap_generated_last', 0) && !variable_get('xmlsitemap_regenerate_needed', FALSE), t('XML sitemaps regenerated and flag cleared.'));
     $this->assertTrue(variable_get('xmlsitemap_generated_last', 0) && !variable_get('xmlsitemap_regenerate_needed', FALSE), t('XML sitemaps regenerated and flag cleared.'));
   }
   }
 
 
+  /**
+   * Assert Sitemap Link.
+   */
   protected function assertSitemapLink($entity_type, $entity_id = NULL) {
   protected function assertSitemapLink($entity_type, $entity_id = NULL) {
     if (is_array($entity_type)) {
     if (is_array($entity_type)) {
       $links = xmlsitemap_link_load_multiple($entity_type);
       $links = xmlsitemap_link_load_multiple($entity_type);
@@ -97,6 +118,9 @@ class XMLSitemapTestHelper extends DrupalWebTestCase {
     return $link;
     return $link;
   }
   }
 
 
+  /**
+   * Assert No Sitemap Link.
+   */
   protected function assertNoSitemapLink($entity_type, $entity_id = NULL) {
   protected function assertNoSitemapLink($entity_type, $entity_id = NULL) {
     if (is_array($entity_type)) {
     if (is_array($entity_type)) {
       $links = xmlsitemap_link_load_multiple($entity_type);
       $links = xmlsitemap_link_load_multiple($entity_type);
@@ -109,54 +133,94 @@ class XMLSitemapTestHelper extends DrupalWebTestCase {
     return $link;
     return $link;
   }
   }
 
 
+  /**
+   * Assert Sitemap Link Visible.
+   */
   protected function assertSitemapLinkVisible($entity_type, $entity_id) {
   protected function assertSitemapLinkVisible($entity_type, $entity_id) {
     $link = xmlsitemap_link_load($entity_type, $entity_id);
     $link = xmlsitemap_link_load($entity_type, $entity_id);
     $this->assertTrue($link && $link['access'] && $link['status'], t('Sitemap link @type @id is visible.', array('@type' => $entity_type, '@id' => $entity_id)));
     $this->assertTrue($link && $link['access'] && $link['status'], t('Sitemap link @type @id is visible.', array('@type' => $entity_type, '@id' => $entity_id)));
   }
   }
 
 
+  /**
+   * Assert Sitemap Link Not Visible.
+   */
   protected function assertSitemapLinkNotVisible($entity_type, $entity_id) {
   protected function assertSitemapLinkNotVisible($entity_type, $entity_id) {
     $link = xmlsitemap_link_load($entity_type, $entity_id);
     $link = xmlsitemap_link_load($entity_type, $entity_id);
-    $this->assertTrue($link && !($link['access'] && $link['status']), t('Sitemap link @type @id is not visible.', array('@type' => $entity_type, '@id' => $entity_id)));
+    $this->assertTrue($link && !($link['access'] && $link['status']), t('Sitemap link @type @id is not visible.', array(
+      '@type' => $entity_type,
+      '@id' => $entity_id,
+    )));
   }
   }
 
 
+  /**
+   * Assert Sitemap Link Values.
+   */
   protected function assertSitemapLinkValues($entity_type, $entity_id, array $conditions) {
   protected function assertSitemapLinkValues($entity_type, $entity_id, array $conditions) {
     $link = xmlsitemap_link_load($entity_type, $entity_id);
     $link = xmlsitemap_link_load($entity_type, $entity_id);
 
 
     if (!$link) {
     if (!$link) {
-      return $this->fail(t('Could not load sitemap link for @type @id.', array('@type' => $entity_type, '@id' => $entity_id)));
+      return $this->fail(t('Could not load sitemap link for @type @id.', array(
+        '@type' => $entity_type,
+        '@id' => $entity_id,
+      )));
     }
     }
 
 
     foreach ($conditions as $key => $value) {
     foreach ($conditions as $key => $value) {
       if ($value === NULL || $link[$key] === NULL) {
       if ($value === NULL || $link[$key] === NULL) {
         // For nullable fields, always check for identical values (===).
         // For nullable fields, always check for identical values (===).
-        $this->assertIdentical($link[$key], $value, t('Identical values for @type @id link field @key.', array('@type' => $entity_type, '@id' => $entity_id, '@key' => $key)));
+        $this->assertIdentical($link[$key], $value, t('Identical values for @type @id link field @key.', array(
+          '@type' => $entity_type,
+          '@id' => $entity_id,
+          '@key' => $key,
+        )));
       }
       }
       else {
       else {
         // Otherwise check simple equality (==).
         // Otherwise check simple equality (==).
-        $this->assertEqual($link[$key], $value, t('Equal values for @type @id link field @key.', array('@type' => $entity_type, '@id' => $entity_id, '@key' => $key)));
+        $this->assertEqual($link[$key], $value, t('Equal values for @type @id link field @key.', array(
+          '@type' => $entity_type,
+          '@id' => $entity_id,
+          '@key' => $key,
+        )));
       }
       }
     }
     }
   }
   }
 
 
+  /**
+   * Assert Not Sitemap Link Values.
+   */
   protected function assertNotSitemapLinkValues($entity_type, $entity_id, array $conditions) {
   protected function assertNotSitemapLinkValues($entity_type, $entity_id, array $conditions) {
     $link = xmlsitemap_link_load($entity_type, $entity_id);
     $link = xmlsitemap_link_load($entity_type, $entity_id);
 
 
     if (!$link) {
     if (!$link) {
-      return $this->fail(t('Could not load sitemap link for @type @id.', array('@type' => $entity_type, '@id' => $entity_id)));
+      return $this->fail(t('Could not load sitemap link for @type @id.', array(
+        '@type' => $entity_type,
+        '@id' => $entity_id,
+      )));
     }
     }
 
 
     foreach ($conditions as $key => $value) {
     foreach ($conditions as $key => $value) {
       if ($value === NULL || $link[$key] === NULL) {
       if ($value === NULL || $link[$key] === NULL) {
         // For nullable fields, always check for identical values (===).
         // For nullable fields, always check for identical values (===).
-        $this->assertNotIdentical($link[$key], $value, t('Not identical values for @type @id link field @key.', array('@type' => $entity_type, '@id' => $entity_id, '@key' => $key)));
+        $this->assertNotIdentical($link[$key], $value, t('Not identical values for @type @id link field @key.', array(
+          '@type' => $entity_type,
+          '@id' => $entity_id,
+          '@key' => $key,
+        )));
       }
       }
       else {
       else {
         // Otherwise check simple equality (==).
         // Otherwise check simple equality (==).
-        $this->assertNotEqual($link[$key], $value, t('Not equal values for link @type @id field @key.', array('@type' => $entity_type, '@id' => $entity_id, '@key' => $key)));
+        $this->assertNotEqual($link[$key], $value, t('Not equal values for link @type @id field @key.', array(
+          '@type' => $entity_type,
+          '@id' => $entity_id,
+          '@key' => $key,
+        )));
       }
       }
     }
     }
   }
   }
 
 
+  /**
+   * Assert Raw Sitemap Links.
+   */
   protected function assertRawSitemapLinks() {
   protected function assertRawSitemapLinks() {
     $links = func_get_args();
     $links = func_get_args();
     foreach ($links as $link) {
     foreach ($links as $link) {
@@ -165,6 +229,9 @@ class XMLSitemapTestHelper extends DrupalWebTestCase {
     }
     }
   }
   }
 
 
+  /**
+   * Assert No Raw Sitemap Links.
+   */
   protected function assertNoRawSitemapLinks() {
   protected function assertNoRawSitemapLinks() {
     $links = func_get_args();
     $links = func_get_args();
     foreach ($links as $link) {
     foreach ($links as $link) {
@@ -173,6 +240,9 @@ class XMLSitemapTestHelper extends DrupalWebTestCase {
     }
     }
   }
   }
 
 
+  /**
+   * Add Sitemap Link.
+   */
   protected function addSitemapLink(array $link = array()) {
   protected function addSitemapLink(array $link = array()) {
     $last_id = &drupal_static(__FUNCTION__, 1);
     $last_id = &drupal_static(__FUNCTION__, 1);
 
 
@@ -191,6 +261,9 @@ class XMLSitemapTestHelper extends DrupalWebTestCase {
     return $link;
     return $link;
   }
   }
 
 
+  /**
+   * Assert Flag.
+   */
   protected function assertFlag($variable, $assert_value = TRUE, $reset_if_true = TRUE) {
   protected function assertFlag($variable, $assert_value = TRUE, $reset_if_true = TRUE) {
     $value = xmlsitemap_var($variable);
     $value = xmlsitemap_var($variable);
 
 
@@ -201,7 +274,13 @@ class XMLSitemapTestHelper extends DrupalWebTestCase {
     return $this->assertEqual($value, $assert_value, "xmlsitemap_$variable is " . ($assert_value ? 'TRUE' : 'FALSE'));
     return $this->assertEqual($value, $assert_value, "xmlsitemap_$variable is " . ($assert_value ? 'TRUE' : 'FALSE'));
   }
   }
 
 
+  /**
+   * Assert XML Sitemap Problems.
+   *
+   * @codingStandardsIgnoreStart
+   */
   protected function assertXMLSitemapProblems($problem_text = FALSE) {
   protected function assertXMLSitemapProblems($problem_text = FALSE) {
+    // @codingStandardsIgnoreEnd
     $this->drupalGet('admin/config/search/xmlsitemap');
     $this->drupalGet('admin/config/search/xmlsitemap');
     $this->assertText(t('One or more problems were detected with your XML sitemap configuration'));
     $this->assertText(t('One or more problems were detected with your XML sitemap configuration'));
     if ($problem_text) {
     if ($problem_text) {
@@ -209,7 +288,13 @@ class XMLSitemapTestHelper extends DrupalWebTestCase {
     }
     }
   }
   }
 
 
+  /**
+   * Assert No XML Sitemap Problems.
+   *
+   * @codingStandardsIgnoreStart
+   */
   protected function assertNoXMLSitemapProblems() {
   protected function assertNoXMLSitemapProblems() {
+    // @codingStandardsIgnoreEnd
     $this->drupalGet('admin/config/search/xmlsitemap');
     $this->drupalGet('admin/config/search/xmlsitemap');
     $this->assertNoText(t('One or more problems were detected with your XML sitemap configuration'));
     $this->assertNoText(t('One or more problems were detected with your XML sitemap configuration'));
   }
   }
@@ -228,7 +313,14 @@ class XMLSitemapTestHelper extends DrupalWebTestCase {
     }
     }
 
 
     $query = db_select('watchdog');
     $query = db_select('watchdog');
-    $query->fields('watchdog', array('wid', 'type', 'severity', 'message', 'variables', 'timestamp'));
+    $query->fields('watchdog', array(
+      'wid',
+      'type',
+      'severity',
+      'message',
+      'variables',
+      'timestamp',
+    ));
     foreach ($conditions as $field => $value) {
     foreach ($conditions as $field => $value) {
       if ($field == 'variables' && !is_string($value)) {
       if ($field == 'variables' && !is_string($value)) {
         $value = serialize($value);
         $value = serialize($value);
@@ -245,10 +337,16 @@ class XMLSitemapTestHelper extends DrupalWebTestCase {
     return $messages;
     return $messages;
   }
   }
 
 
+  /**
+   * Assert Watchdog Message.
+   */
   protected function assertWatchdogMessage(array $conditions, $message = 'Watchdog message found.') {
   protected function assertWatchdogMessage(array $conditions, $message = 'Watchdog message found.') {
     $this->assertTrue($this->getWatchdogMessages($conditions), $message);
     $this->assertTrue($this->getWatchdogMessages($conditions), $message);
   }
   }
 
 
+  /**
+   * Assert No Watchdog Message.
+   */
   protected function assertNoWatchdogMessage(array $conditions, $message = 'Watchdog message not found.') {
   protected function assertNoWatchdogMessage(array $conditions, $message = 'Watchdog message not found.') {
     $this->assertFalse($this->getWatchdogMessages($conditions), $message);
     $this->assertFalse($this->getWatchdogMessages($conditions), $message);
   }
   }
@@ -262,7 +360,13 @@ class XMLSitemapTestHelper extends DrupalWebTestCase {
 
 
     foreach ($messages as $message) {
     foreach ($messages as $message) {
       $message->text = $this->formatWatchdogMessage($message);
       $message->text = $this->formatWatchdogMessage($message);
-      if (in_array($message->severity, array(WATCHDOG_EMERGENCY, WATCHDOG_ALERT, WATCHDOG_CRITICAL, WATCHDOG_ERROR, WATCHDOG_WARNING))) {
+      if (in_array($message->severity, array(
+        WATCHDOG_EMERGENCY,
+        WATCHDOG_ALERT,
+        WATCHDOG_CRITICAL,
+        WATCHDOG_ERROR,
+        WATCHDOG_WARNING,
+      ))) {
         $this->fail($message->text);
         $this->fail($message->text);
       }
       }
       $verbose[] = $message->text;
       $verbose[] = $message->text;
@@ -280,9 +384,10 @@ class XMLSitemapTestHelper extends DrupalWebTestCase {
   /**
   /**
    * Format a watchdog message in a one-line summary.
    * Format a watchdog message in a one-line summary.
    *
    *
-   * @param $message
-   *   A watchdog messsage object.
-   * @return
+   * @param object $message
+   *   A watchdog message object.
+   *
+   * @return string
    *   A string containing the watchdog message's timestamp, severity, type,
    *   A string containing the watchdog message's timestamp, severity, type,
    *   and actual message.
    *   and actual message.
    */
    */
@@ -308,13 +413,14 @@ class XMLSitemapTestHelper extends DrupalWebTestCase {
    * This is a copy of DrupalWebTestCase->verbose() but allows a customizable
    * This is a copy of DrupalWebTestCase->verbose() but allows a customizable
    * summary message rather than hard-coding 'Verbose message'.
    * summary message rather than hard-coding 'Verbose message'.
    *
    *
-   * @param $verbose_message
+   * @param string $verbose_message
    *   The verbose message to be stored.
    *   The verbose message to be stored.
-   * @param $message
+   * @param string $message
    *   Message to display.
    *   Message to display.
+   *
    * @see simpletest_verbose()
    * @see simpletest_verbose()
    *
    *
-   * @todo Remove when http://drupal.org/node/800426 is fixed.
+   * @todo Remove when https://www.drupal.org/node/800426 is fixed.
    */
    */
   protected function verbose($verbose_message, $message = 'Verbose message') {
   protected function verbose($verbose_message, $message = 'Verbose message') {
     if ($id = simpletest_verbose($verbose_message)) {
     if ($id = simpletest_verbose($verbose_message)) {
@@ -322,9 +428,17 @@ class XMLSitemapTestHelper extends DrupalWebTestCase {
       $this->error(l($message, $url, array('attributes' => array('target' => '_blank'))), 'User notice');
       $this->error(l($message, $url, array('attributes' => array('target' => '_blank'))), 'User notice');
     }
     }
   }
   }
+
 }
 }
 
 
+/**
+ * XML Sitemap UnitTest.
+ */
 class XMLSitemapUnitTest extends XMLSitemapTestHelper {
 class XMLSitemapUnitTest extends XMLSitemapTestHelper {
+
+  /**
+   * Get Info.
+   */
   public static function getInfo() {
   public static function getInfo() {
     return array(
     return array(
       'name' => 'XML sitemap unit tests',
       'name' => 'XML sitemap unit tests',
@@ -333,7 +447,10 @@ class XMLSitemapUnitTest extends XMLSitemapTestHelper {
     );
     );
   }
   }
 
 
-  function testAssertFlag() {
+  /**
+   * Test Assert Flag.
+   */
+  public function testAssertFlag() {
     variable_set('xmlsitemap_rebuild_needed', TRUE);
     variable_set('xmlsitemap_rebuild_needed', TRUE);
     $this->assertTrue(xmlsitemap_var('rebuild_needed'));
     $this->assertTrue(xmlsitemap_var('rebuild_needed'));
     $this->assertTrue($this->assertFlag('rebuild_needed', TRUE, FALSE));
     $this->assertTrue($this->assertFlag('rebuild_needed', TRUE, FALSE));
@@ -347,7 +464,7 @@ class XMLSitemapUnitTest extends XMLSitemapTestHelper {
   /**
   /**
    * Tests for xmlsitemap_get_changefreq().
    * Tests for xmlsitemap_get_changefreq().
    */
    */
-  function testGetChangefreq() {
+  public function testGetChangefreq() {
     // The test values.
     // The test values.
     $values = array(
     $values = array(
       0,
       0,
@@ -381,7 +498,7 @@ class XMLSitemapUnitTest extends XMLSitemapTestHelper {
   /**
   /**
    * Tests for xmlsitemap_get_chunk_count().
    * Tests for xmlsitemap_get_chunk_count().
    */
    */
-  function testGetChunkCount() {
+  public function testGetChunkCount() {
     // Set a low chunk size for testing.
     // Set a low chunk size for testing.
     variable_set('xmlsitemap_chunk_size', 4);
     variable_set('xmlsitemap_chunk_size', 4);
 
 
@@ -407,24 +524,27 @@ class XMLSitemapUnitTest extends XMLSitemapTestHelper {
     $this->assertEqual(xmlsitemap_get_link_count(), 0);
     $this->assertEqual(xmlsitemap_get_link_count(), 0);
 
 
     // Delete all links. The chunk count should be 1 not 0.
     // Delete all links. The chunk count should be 1 not 0.
-    db_query("DELETE FROM {xmlsitemap}");
+    db_delete('xmlsitemap')->execute();
+
     $this->assertEqual(db_query("SELECT COUNT(id) FROM {xmlsitemap}")->fetchField(), 0);
     $this->assertEqual(db_query("SELECT COUNT(id) FROM {xmlsitemap}")->fetchField(), 0);
     $this->assertEqual(xmlsitemap_get_chunk_count(TRUE), 1);
     $this->assertEqual(xmlsitemap_get_chunk_count(TRUE), 1);
   }
   }
 
 
-  //function testGetChunkFile() {
-  //}
+  // @codingStandardsIgnoreStart
+  // Function testGetChunkFile() {
+  // }
   //
   //
-  //function testGetChunkSize() {
-  //}
+  // function testGetChunkSize() {
+  // }
   //
   //
-  //function testGetLinkCount() {
-  //}
+  // function testGetLinkCount() {
+  // }
+  // @codingStandardsIgnoreEnd
 
 
   /**
   /**
    * Tests for xmlsitemap_calculate_changereq().
    * Tests for xmlsitemap_calculate_changereq().
    */
    */
-  function testCalculateChangefreq() {
+  public function testCalculateChangefreq() {
     // The test values.
     // The test values.
     $values = array(
     $values = array(
       array(),
       array(),
@@ -439,16 +559,19 @@ class XMLSitemapUnitTest extends XMLSitemapTestHelper {
     foreach ($values as $i => $value) {
     foreach ($values as $i => $value) {
       $actual = xmlsitemap_calculate_changefreq($value);
       $actual = xmlsitemap_calculate_changefreq($value);
       $this->assertEqual($actual, $expected[$i]);
       $this->assertEqual($actual, $expected[$i]);
-
     }
     }
   }
   }
 
 
   /**
   /**
    * Test for xmlsitemap_recalculate_changefreq().
    * Test for xmlsitemap_recalculate_changefreq().
    */
    */
-  function testRecalculateChangefreq() {
+  public function testRecalculateChangefreq() {
     // The starting test value.
     // The starting test value.
-    $value = array('lastmod' => REQUEST_TIME - 1000, 'changefreq' => 0, 'changecount' => 0);
+    $value = array(
+      'lastmod' => REQUEST_TIME - 1000,
+      'changefreq' => 0,
+      'changecount' => 0,
+    );
 
 
     // Expected values.
     // Expected values.
     $expecteds = array(
     $expecteds = array(
@@ -466,7 +589,7 @@ class XMLSitemapUnitTest extends XMLSitemapTestHelper {
   /**
   /**
    * Tests for xmlsitemap_switch_user and xmlsitemap_restore_user().
    * Tests for xmlsitemap_switch_user and xmlsitemap_restore_user().
    */
    */
-  function testSwitchUser() {
+  public function testSwitchUser() {
     global $user;
     global $user;
 
 
     $original_user = $user;
     $original_user = $user;
@@ -509,14 +632,21 @@ class XMLSitemapUnitTest extends XMLSitemapTestHelper {
     $this->assertEqual($user->uid, 0);
     $this->assertEqual($user->uid, 0);
   }
   }
 
 
-  //function testLoadLink() {
-  //}
+  // @codingStandardsIgnoreStart
+  // function testLoadLink() {
+  // }
+  // @codingStandardsIgnoreEnd
 
 
   /**
   /**
    * Tests for xmlsitemap_link_save().
    * Tests for xmlsitemap_link_save().
    */
    */
-  function testSaveLink() {
-    $link = array('type' => 'testing', 'id' => 1, 'loc' => 'testing', 'status' => 1);
+  public function testSaveLink() {
+    $link = array(
+      'type' => 'testing',
+      'id' => 1,
+      'loc' => 'testing',
+      'status' => 1,
+    );
     xmlsitemap_link_save($link);
     xmlsitemap_link_save($link);
     $this->assertFlag('regenerate_needed', TRUE);
     $this->assertFlag('regenerate_needed', TRUE);
 
 
@@ -564,7 +694,7 @@ class XMLSitemapUnitTest extends XMLSitemapTestHelper {
   /**
   /**
    * Tests for xmlsitemap_link_delete().
    * Tests for xmlsitemap_link_delete().
    */
    */
-  function testLinkDelete() {
+  public function testLinkDelete() {
     // Add our testing data.
     // Add our testing data.
     $link1 = $this->addSitemapLink(array('loc' => 'testing1', 'status' => 0));
     $link1 = $this->addSitemapLink(array('loc' => 'testing1', 'status' => 0));
     $link2 = $this->addSitemapLink(array('loc' => 'testing1', 'status' => 1));
     $link2 = $this->addSitemapLink(array('loc' => 'testing1', 'status' => 1));
@@ -589,55 +719,67 @@ class XMLSitemapUnitTest extends XMLSitemapTestHelper {
   /**
   /**
    * Tests for xmlsitemap_link_update_multiple().
    * Tests for xmlsitemap_link_update_multiple().
    */
    */
-  function testUpdateLinks() {
+  public function testUpdateLinks() {
     // Add our testing data.
     // Add our testing data.
     $links = array();
     $links = array();
     $links[1] = $this->addSitemapLink(array('subtype' => 'group1'));
     $links[1] = $this->addSitemapLink(array('subtype' => 'group1'));
     $links[2] = $this->addSitemapLink(array('subtype' => 'group1'));
     $links[2] = $this->addSitemapLink(array('subtype' => 'group1'));
     $links[3] = $this->addSitemapLink(array('subtype' => 'group2'));
     $links[3] = $this->addSitemapLink(array('subtype' => 'group2'));
     variable_set('xmlsitemap_regenerate_needed', FALSE);
     variable_set('xmlsitemap_regenerate_needed', FALSE);
-    // id | type    | subtype | language | access | status | priority
+    // Id | type    | subtype | language | access | status | priority
     // 1  | testing | group1  | ''       | 1      | 1      | 0.5
     // 1  | testing | group1  | ''       | 1      | 1      | 0.5
     // 2  | testing | group1  | ''       | 1      | 1      | 0.5
     // 2  | testing | group1  | ''       | 1      | 1      | 0.5
-    // 3  | testing | group2  | ''       | 1      | 1      | 0.5
-
-    $updated = xmlsitemap_link_update_multiple(array('status' => 0), array('type' => 'testing', 'subtype' => 'group1', 'status_override' => 0));
+    // 3  | testing | group2  | ''       | 1      | 1      | 0.5.
+    $updated = xmlsitemap_link_update_multiple(array('status' => 0), array(
+      'type' => 'testing',
+      'subtype' => 'group1',
+      'status_override' => 0,
+    ));
     $this->assertEqual($updated, 2);
     $this->assertEqual($updated, 2);
     $this->assertFlag('regenerate_needed', TRUE);
     $this->assertFlag('regenerate_needed', TRUE);
-    // id | type    | subtype | language | status | priority
+    // Id | type    | subtype | language | status | priority
     // 1  | testing | group1  | ''       | 0      | 0.5
     // 1  | testing | group1  | ''       | 0      | 0.5
     // 2  | testing | group1  | ''       | 0      | 0.5
     // 2  | testing | group1  | ''       | 0      | 0.5
-    // 3  | testing | group2  | ''       | 1      | 0.5
-
-    $updated = xmlsitemap_link_update_multiple(array('priority' => 0.0), array('type' => 'testing', 'subtype' => 'group1', 'priority_override' => 0));
+    // 3  | testing | group2  | ''       | 1      | 0.5.
+    $updated = xmlsitemap_link_update_multiple(array('priority' => 0.0), array(
+      'type' => 'testing',
+      'subtype' => 'group1',
+      'priority_override' => 0,
+    ));
     $this->assertEqual($updated, 2);
     $this->assertEqual($updated, 2);
     $this->assertFlag('regenerate_needed', FALSE);
     $this->assertFlag('regenerate_needed', FALSE);
-    // id | type    | subtype | language | status | priority
+    // Id | type    | subtype | language | status | priority
     // 1  | testing | group1  | ''       | 0      | 0.0
     // 1  | testing | group1  | ''       | 0      | 0.0
     // 2  | testing | group1  | ''       | 0      | 0.0
     // 2  | testing | group1  | ''       | 0      | 0.0
-    // 3  | testing | group2  | ''       | 1      | 0.5
-
-    $updated = xmlsitemap_link_update_multiple(array('subtype' => 'group2'), array('type' => 'testing', 'subtype' => 'group1'));
+    // 3  | testing | group2  | ''       | 1      | 0.5.
+    $updated = xmlsitemap_link_update_multiple(array('subtype' => 'group2'), array(
+      'type' => 'testing',
+      'subtype' => 'group1',
+    ));
     $this->assertEqual($updated, 2);
     $this->assertEqual($updated, 2);
     $this->assertFlag('regenerate_needed', FALSE);
     $this->assertFlag('regenerate_needed', FALSE);
-    // id | type    | subtype | language | status | priority
+    // Id | type    | subtype | language | status | priority
     // 1  | testing | group2  | ''       | 0      | 0.0
     // 1  | testing | group2  | ''       | 0      | 0.0
     // 2  | testing | group2  | ''       | 0      | 0.0
     // 2  | testing | group2  | ''       | 0      | 0.0
-    // 3  | testing | group2  | ''       | 1      | 0.5
-
-    $updated = xmlsitemap_link_update_multiple(array('status' => 1), array('type' => 'testing', 'subtype' => 'group2', 'status_override' => 0, 'status' => 0));
+    // 3  | testing | group2  | ''       | 1      | 0.5.
+    $updated = xmlsitemap_link_update_multiple(array('status' => 1), array(
+      'type' => 'testing',
+      'subtype' => 'group2',
+      'status_override' => 0,
+      'status' => 0,
+    ));
     $this->assertEqual($updated, 2);
     $this->assertEqual($updated, 2);
     $this->assertFlag('regenerate_needed', TRUE);
     $this->assertFlag('regenerate_needed', TRUE);
-    // id | type    | subtype | language | status | priority
+    // Id | type    | subtype | language | status | priority
     // 1  | testing | group2  | ''       | 1      | 0.0
     // 1  | testing | group2  | ''       | 1      | 0.0
     // 2  | testing | group2  | ''       | 1      | 0.0
     // 2  | testing | group2  | ''       | 1      | 0.0
-    // 3  | testing | group2  | ''       | 1      | 0.5
+    // 3  | testing | group2  | ''       | 1      | 0.5.
   }
   }
 
 
   /**
   /**
    * Test that duplicate paths are skipped during generation.
    * Test that duplicate paths are skipped during generation.
    */
    */
-  function testDuplicatePaths() {
+  public function testDuplicatePaths() {
     $link1 = $this->addSitemapLink(array('loc' => 'duplicate'));
     $link1 = $this->addSitemapLink(array('loc' => 'duplicate'));
     $link2 = $this->addSitemapLink(array('loc' => 'duplicate'));
     $link2 = $this->addSitemapLink(array('loc' => 'duplicate'));
     $this->regenerateSitemap();
     $this->regenerateSitemap();
@@ -648,7 +790,7 @@ class XMLSitemapUnitTest extends XMLSitemapTestHelper {
   /**
   /**
    * Test that the sitemap will not be genereated before the lifetime expires.
    * Test that the sitemap will not be genereated before the lifetime expires.
    */
    */
-  function testMinimumLifetime() {
+  public function testMinimumLifetime() {
     variable_set('xmlsitemap_minimum_lifetime', 300);
     variable_set('xmlsitemap_minimum_lifetime', 300);
     $this->regenerateSitemap();
     $this->regenerateSitemap();
 
 
@@ -673,9 +815,17 @@ class XMLSitemapUnitTest extends XMLSitemapTestHelper {
     $this->assertResponse(200);
     $this->assertResponse(200);
     $this->assertNoRaw('lifetime-test');
     $this->assertNoRaw('lifetime-test');
   }
   }
+
 }
 }
 
 
+/**
+ * XML Sitemap Functional Test.
+ */
 class XMLSitemapFunctionalTest extends XMLSitemapTestHelper {
 class XMLSitemapFunctionalTest extends XMLSitemapTestHelper {
+
+  /**
+   * Get Info.
+   */
   public static function getInfo() {
   public static function getInfo() {
     return array(
     return array(
       'name' => 'XML sitemap interface tests',
       'name' => 'XML sitemap interface tests',
@@ -684,17 +834,24 @@ class XMLSitemapFunctionalTest extends XMLSitemapTestHelper {
     );
     );
   }
   }
 
 
-  function setUp($modules = array()) {
+  /**
+   * Setup.
+   */
+  public function setUp($modules = array()) {
     $modules[] = 'path';
     $modules[] = 'path';
     parent::setUp($modules);
     parent::setUp($modules);
-    $this->admin_user = $this->drupalCreateUser(array('access content', 'administer site configuration', 'administer xmlsitemap'));
+    $this->admin_user = $this->drupalCreateUser(array(
+      'access content',
+      'administer site configuration',
+      'administer xmlsitemap',
+    ));
     $this->drupalLogin($this->admin_user);
     $this->drupalLogin($this->admin_user);
   }
   }
 
 
   /**
   /**
    * Test the sitemap file caching.
    * Test the sitemap file caching.
    */
    */
-  function testSitemapCaching() {
+  public function testSitemapCaching() {
     $this->regenerateSitemap();
     $this->regenerateSitemap();
     $this->drupalGetSitemap();
     $this->drupalGetSitemap();
     $this->assertResponse(200);
     $this->assertResponse(200);
@@ -709,8 +866,11 @@ class XMLSitemapFunctionalTest extends XMLSitemapTestHelper {
 
 
   /**
   /**
    * Test base URL functionality.
    * Test base URL functionality.
+   *
+   * @codingStandardsIgnoreStart
    */
    */
-  function testBaseURL() {
+  public function testBaseURL() {
+    // @codingStandardsIgnoreEnd
     $edit = array('xmlsitemap_base_url' => '');
     $edit = array('xmlsitemap_base_url' => '');
     $this->drupalPost('admin/config/search/xmlsitemap/settings', $edit, t('Save configuration'));
     $this->drupalPost('admin/config/search/xmlsitemap/settings', $edit, t('Save configuration'));
     $this->assertText(t('Default base URL field is required.'));
     $this->assertText(t('Default base URL field is required.'));
@@ -733,20 +893,24 @@ class XMLSitemapFunctionalTest extends XMLSitemapTestHelper {
   }
   }
 
 
   /**
   /**
-   * Test that configuration problems are reported properly in the status report.
+   * Test Status Report Function.
+   *
+   * Test that configuration problems are reported properly in the status
+   * report.
    */
    */
-  function testStatusReport() {
+  public function testStatusReport() {
     // Test the rebuild flag.
     // Test the rebuild flag.
+    // @codingStandardsIgnoreStart
     // @todo Re-enable these tests once we get a xmlsitemap_test.module.
     // @todo Re-enable these tests once we get a xmlsitemap_test.module.
-    //variable_set('xmlsitemap_generated_last', REQUEST_TIME);
-    //variable_set('xmlsitemap_rebuild_needed', TRUE);
-    //$this->assertXMLSitemapProblems(t('The XML sitemap data is out of sync and needs to be completely rebuilt.'));
-    //$this->clickLink(t('completely rebuilt'));
-    //$this->assertResponse(200);
-    //variable_set('xmlsitemap_rebuild_needed', FALSE);
-    //$this->assertNoXMLSitemapProblems();
-
+    // variable_set('xmlsitemap_generated_last', REQUEST_TIME);
+    // variable_set('xmlsitemap_rebuild_needed', TRUE);
+    // $this->assertXMLSitemapProblems(t('The XML sitemap data is out of sync and needs to be completely rebuilt.'));
+    // $this->clickLink(t('completely rebuilt'));
+    // $this->assertResponse(200);
+    // variable_set('xmlsitemap_rebuild_needed', FALSE);
+    // $this->assertNoXMLSitemapProblems();
     // Test the regenerate flag (and cron hasn't run in a while).
     // Test the regenerate flag (and cron hasn't run in a while).
+    // @codingStandardsIgnoreEnd
     variable_set('xmlsitemap_regenerate_needed', TRUE);
     variable_set('xmlsitemap_regenerate_needed', TRUE);
     variable_set('xmlsitemap_generated_last', REQUEST_TIME - variable_get('cron_threshold_warning', 172800) - 100);
     variable_set('xmlsitemap_generated_last', REQUEST_TIME - variable_get('cron_threshold_warning', 172800) - 100);
     $this->assertXMLSitemapProblems(t('The XML cached files are out of date and need to be regenerated. You can run cron manually to regenerate the sitemap files.'));
     $this->assertXMLSitemapProblems(t('The XML cached files are out of date and need to be regenerated. You can run cron manually to regenerate the sitemap files.'));
@@ -757,9 +921,17 @@ class XMLSitemapFunctionalTest extends XMLSitemapTestHelper {
     // Test chunk count > 1000.
     // Test chunk count > 1000.
     // Test directory not writable.
     // Test directory not writable.
   }
   }
+
 }
 }
 
 
+/**
+ * XML Sitemap Robots Txt Integration Test.
+ */
 class XMLSitemapRobotsTxtIntegrationTest extends XMLSitemapTestHelper {
 class XMLSitemapRobotsTxtIntegrationTest extends XMLSitemapTestHelper {
+
+  /**
+   * Get Info.
+   */
   public static function getInfo() {
   public static function getInfo() {
     return array(
     return array(
       'name' => 'XML sitemap robots.txt',
       'name' => 'XML sitemap robots.txt',
@@ -769,15 +941,22 @@ class XMLSitemapRobotsTxtIntegrationTest extends XMLSitemapTestHelper {
     );
     );
   }
   }
 
 
-  function setUp($modules = array()) {
+  /**
+   * Setup.
+   */
+  public function setUp($modules = array()) {
     $modules[] = 'robotstxt';
     $modules[] = 'robotstxt';
     parent::setUp($modules);
     parent::setUp($modules);
   }
   }
 
 
-  function testRobotsTxt() {
+  /**
+   * Test Robots Txt.
+   */
+  public function testRobotsTxt() {
     // Request the un-clean robots.txt path so this will work in case there is
     // Request the un-clean robots.txt path so this will work in case there is
     // still the robots.txt file in the root directory.
     // still the robots.txt file in the root directory.
     $this->drupalGet('', array('query' => array('q' => 'robots.txt')));
     $this->drupalGet('', array('query' => array('q' => 'robots.txt')));
     $this->assertRaw('Sitemap: ' . url('sitemap.xml', array('absolute' => TRUE)));
     $this->assertRaw('Sitemap: ' . url('sitemap.xml', array('absolute' => TRUE)));
   }
   }
+
 }
 }

+ 97 - 14
sites/all/modules/xmlsitemap/xmlsitemap.xmlsitemap.inc

@@ -5,36 +5,69 @@
  * XML sitemap integration functions for xmlsitemap.module.
  * XML sitemap integration functions for xmlsitemap.module.
  */
  */
 
 
-class XMLSitemapException extends Exception {}
+/**
+ * Class for XML Sitemap Exception.
+ */
+class XMLSitemapException extends Exception {
+
+}
+
+/**
+ * Class for XML Sitemap Generation Exception.
+ */
+class XMLSitemapGenerationException extends XMLSitemapException {
 
 
-class XMLSitemapGenerationException extends XMLSitemapException {}
+}
 
 
 /**
 /**
  * Extended class for writing XML sitemap files.
  * Extended class for writing XML sitemap files.
  */
  */
 class XMLSitemapWriter extends XMLWriter {
 class XMLSitemapWriter extends XMLWriter {
+
   protected $uri = NULL;
   protected $uri = NULL;
   protected $sitemapElementCount = 0;
   protected $sitemapElementCount = 0;
   protected $linkCountFlush = 500;
   protected $linkCountFlush = 500;
   protected $sitemap = NULL;
   protected $sitemap = NULL;
+
+  /**
+   * Sitemap Page.
+   *
+   * @var string
+   *
+   * @codingStandardsIgnoreStart
+   */
   protected $sitemap_page = NULL;
   protected $sitemap_page = NULL;
+
+  /**
+   * Root Element.
+   *
+   * @var string.
+   *
+   * @codingStandardsIgnoreEnd
+   */
   protected $rootElement = 'urlset';
   protected $rootElement = 'urlset';
 
 
   /**
   /**
    * Constructor.
    * Constructor.
    *
    *
-   * @param $sitemap
+   * @param array $sitemap
    *   The sitemap array.
    *   The sitemap array.
-   * @param $page
+   * @param string $page
    *   The current page of the sitemap being generated.
    *   The current page of the sitemap being generated.
+   *
+   * @codingStandardsIgnoreStart
    */
    */
-  function __construct(stdClass $sitemap, $page) {
+  public function __construct(stdClass $sitemap, $page) {
+    // @codingStandardsIgnoreEnd
     $this->sitemap = $sitemap;
     $this->sitemap = $sitemap;
     $this->sitemap_page = $page;
     $this->sitemap_page = $page;
     $this->uri = xmlsitemap_sitemap_get_file($sitemap, $page);
     $this->uri = xmlsitemap_sitemap_get_file($sitemap, $page);
     $this->openUri($this->uri);
     $this->openUri($this->uri);
   }
   }
 
 
+  /**
+   * Open URI.
+   */
   public function openUri($uri) {
   public function openUri($uri) {
     $return = parent::openUri($uri);
     $return = parent::openUri($uri);
     if (!$return) {
     if (!$return) {
@@ -43,6 +76,9 @@ class XMLSitemapWriter extends XMLWriter {
     return $return;
     return $return;
   }
   }
 
 
+  /**
+   * Start Document.
+   */
   public function startDocument($version = '1.0', $encoding = 'UTF-8', $standalone = NULL) {
   public function startDocument($version = '1.0', $encoding = 'UTF-8', $standalone = NULL) {
     $this->setIndent(FALSE);
     $this->setIndent(FALSE);
     $result = parent::startDocument($version, $encoding);
     $result = parent::startDocument($version, $encoding);
@@ -56,11 +92,15 @@ class XMLSitemapWriter extends XMLWriter {
     return $result;
     return $result;
   }
   }
 
 
+  /**
+   * Get Sitemap URL.
+   */
   public function getSitemapUrl($path, array $options = array()) {
   public function getSitemapUrl($path, array $options = array()) {
+    global $base_url;
     $options += $this->sitemap->uri['options'];
     $options += $this->sitemap->uri['options'];
     $options += array(
     $options += array(
       'absolute' => TRUE,
       'absolute' => TRUE,
-      'base_url' => variable_get('xmlsitemap_base_url', $GLOBALS['base_url']),
+      'base_url' => variable_get('xmlsitemap_base_url', $base_url),
       'language' => language_default(),
       'language' => language_default(),
       'alias' => TRUE,
       'alias' => TRUE,
     );
     );
@@ -72,9 +112,12 @@ class XMLSitemapWriter extends XMLWriter {
 
 
   /**
   /**
    * Add the XML stylesheet to the XML page.
    * Add the XML stylesheet to the XML page.
+   *
+   * @codingStandardsIgnoreStart
    */
    */
   public function writeXSL() {
   public function writeXSL() {
-    $this->writePi('xml-stylesheet', 'type="text/xsl" href="' . $this->getSitemapUrl('sitemap.xsl', array('protocol_relative' => TRUE)) . '"');
+    // @codingStandardsIgnoreEnd
+    $this->writePi('xml-stylesheet', 'type="text/xsl" href="' . $this->getSitemapUrl('sitemap.xsl', array('absolute' => FALSE)) . '"');
     $this->writeRaw(PHP_EOL);
     $this->writeRaw(PHP_EOL);
   }
   }
 
 
@@ -93,10 +136,19 @@ class XMLSitemapWriter extends XMLWriter {
     return $attributes;
     return $attributes;
   }
   }
 
 
+  /**
+   * Generate XML.
+   *
+   * @codingStandardsIgnoreStart
+   */
   public function generateXML() {
   public function generateXML() {
+    // @codingStandardsIgnoreEnd
     return xmlsitemap_generate_chunk($this->sitemap, $this, $this->sitemap_page);
     return xmlsitemap_generate_chunk($this->sitemap, $this, $this->sitemap_page);
   }
   }
 
 
+  /**
+   * Start Element.
+   */
   public function startElement($name, $root = FALSE) {
   public function startElement($name, $root = FALSE) {
     parent::startElement($name);
     parent::startElement($name);
 
 
@@ -111,9 +163,9 @@ class XMLSitemapWriter extends XMLWriter {
   /**
   /**
    * Write an full XML sitemap element tag.
    * Write an full XML sitemap element tag.
    *
    *
-   * @param $name
+   * @param string $name
    *   The element name.
    *   The element name.
-   * @param $element
+   * @param array $element
    *   An array of the elements properties and values.
    *   An array of the elements properties and values.
    */
    */
   public function writeSitemapElement($name, array &$element) {
   public function writeSitemapElement($name, array &$element) {
@@ -152,14 +204,26 @@ class XMLSitemapWriter extends XMLWriter {
     }
     }
   }
   }
 
 
+  /**
+   * Get URI.
+   *
+   * @codingStandardsIgnoreStart
+   */
   public function getURI() {
   public function getURI() {
+    // @codingStandardsIgnoreEnd
     return $this->uri;
     return $this->uri;
   }
   }
 
 
+  /**
+   * Get Count Sitemap Element.
+   */
   public function getSitemapElementCount() {
   public function getSitemapElementCount() {
     return $this->sitemapElementCount;
     return $this->sitemapElementCount;
   }
   }
 
 
+  /**
+   * Document.
+   */
   public function endDocument() {
   public function endDocument() {
     $return = parent::endDocument();
     $return = parent::endDocument();
 
 
@@ -167,22 +231,34 @@ class XMLSitemapWriter extends XMLWriter {
       throw new XMLSitemapGenerationException(t('Unknown error occurred while writing to file @file.', array('@file' => $this->uri)));
       throw new XMLSitemapGenerationException(t('Unknown error occurred while writing to file @file.', array('@file' => $this->uri)));
     }
     }
 
 
-    //if (xmlsitemap_var('gz')) {
+    // @code
+    // If (xmlsitemap_var('gz')) {
     //  $file_gz = $file . '.gz';
     //  $file_gz = $file . '.gz';
     //  file_put_contents($file_gz, gzencode(file_get_contents($file), 9));
     //  file_put_contents($file_gz, gzencode(file_get_contents($file), 9));
-    //}
-
+    // }
+    // @endcode
     return $return;
     return $return;
   }
   }
+
 }
 }
 
 
+/**
+ * XML Sitemap Index Writer.
+ */
 class XMLSitemapIndexWriter extends XMLSitemapWriter {
 class XMLSitemapIndexWriter extends XMLSitemapWriter {
+
   protected $rootElement = 'sitemapindex';
   protected $rootElement = 'sitemapindex';
 
 
-  function __construct(stdClass $sitemap, $page = 'index') {
+  /**
+   * Construct.
+   */
+  public function __construct(stdClass $sitemap, $page = 'index') {
     parent::__construct($sitemap, 'index');
     parent::__construct($sitemap, 'index');
   }
   }
 
 
+  /**
+   * Get Root Attributes.
+   */
   public function getRootAttributes() {
   public function getRootAttributes() {
     $attributes['xmlns'] = 'http://www.sitemaps.org/schemas/sitemap/0.9';
     $attributes['xmlns'] = 'http://www.sitemaps.org/schemas/sitemap/0.9';
     if (variable_get('xmlsitemap_developer_mode', 0)) {
     if (variable_get('xmlsitemap_developer_mode', 0)) {
@@ -195,7 +271,13 @@ class XMLSitemapIndexWriter extends XMLSitemapWriter {
     return $attributes;
     return $attributes;
   }
   }
 
 
+  /**
+   * Generate XML.
+   *
+   * @codingStandardsIgnoreStart
+   */
   public function generateXML() {
   public function generateXML() {
+    // @codingStandardsIgnoreEnd
     $lastmod_format = variable_get('xmlsitemap_lastmod_format', XMLSITEMAP_LASTMOD_MEDIUM);
     $lastmod_format = variable_get('xmlsitemap_lastmod_format', XMLSITEMAP_LASTMOD_MEDIUM);
 
 
     for ($i = 1; $i <= $this->sitemap->chunks; $i++) {
     for ($i = 1; $i <= $this->sitemap->chunks; $i++) {
@@ -207,6 +289,7 @@ class XMLSitemapIndexWriter extends XMLSitemapWriter {
       $this->writeSitemapElement('sitemap', $element);
       $this->writeSitemapElement('sitemap', $element);
     }
     }
   }
   }
+
 }
 }
 
 
 /**
 /**
@@ -285,7 +368,7 @@ function xmlsitemap_xmlsitemap_sitemap_operations() {
 /**
 /**
  * XML sitemap operation callback; regenerate sitemap files using the batch API.
  * XML sitemap operation callback; regenerate sitemap files using the batch API.
  *
  *
- * @param $smids
+ * @param array $smids
  *   An array of XML sitemap IDs.
  *   An array of XML sitemap IDs.
  *
  *
  * @see xmlsitemap_regenerate_batch()
  * @see xmlsitemap_regenerate_batch()

+ 76 - 0
sites/all/modules/xmlsitemap/xmlsitemap_custom/README.txt

@@ -0,0 +1,76 @@
+CONTENTS OF THIS FILE
+---------------------
+
+* Introduction
+* Requirements
+* Recommended modules
+* Installation
+* Configuration
+* Maintainers
+
+
+INTRODUCTION
+------------
+
+The XML sitemap custom module, part of the XML sitemap
+(https://www.drupal.org/project/xmlsitemap) package, adds user configurable
+links to the sitemap. The XML sitemap module creates a sitemap that conforms to
+the sitemaps.org specification. This helps search engines to more intelligently
+crawl a website and keep their results up to date.
+
+* For a full description of the module, visit
+  https://www.drupal.org/documentation/modules/xmlsitemap
+
+* To submit bug reports and feature suggestions, or to track changes visit
+  https://www.drupal.org/project/issues/xmlsitemap
+
+
+REQUIREMENTS
+------------
+
+This module requires the following module:
+
+* XML sitemap - https://www.drupal.org/project/xmlsitemap
+
+
+RECOMMENDED MODULES
+-------------------
+
+* Ctools - https://www.drupal.org/project/ctools
+* RobotsTxt - https://www.drupal.org/project/robotstxt
+* Site Verification - https://www.drupal.org/project/site_verify
+* Browscap - https://www.drupal.org/project/browscap
+* Vertical Tabs - https://www.drupal.org/project/vertical_tabs
+
+
+INSTALLATION
+------------
+
+This is a submodule of the XML sitemap module. Install the XML sitemap module as
+you would normally install a contributed Drupal module. Visit
+https://www.drupal.org/node/895232 for further information.
+
+
+CONFIGURATION
+-------------
+
+1. Install the XML sitemap module.
+2. Enable the XML sitemap module.
+3. To include custom links in the sitemap, enable the XML custom submodule.
+4. Navigate to Administration > Configuration > Search > XML Sitemap.
+5. Select on the Custom Links tab to add a custom link.
+6. Enter the address and select Save.
+7. Select on the XML sitemap vertical tab.
+8. Select on the Rebuild Links tab in the upper right.
+9. Select on "Rebuild sitemap" even if the message says that you do not need to.
+10. Now you're taken back to the config page which shows you the link to your
+    XML sitemap which you can click and confirm that pages have been added.
+
+
+MAINTAINERS
+-----------
+
+* Andrei Mateescu (amateescu) - https://www.drupal.org/u/amateescu
+* Dave Reid - https://www.drupal.org/u/dave-reid
+* Juampy NR (juampynr) - https://www.drupal.org/u/juampynr
+* Tasya Rukmana (tadityar) - https://www.drupal.org/u/tadityar

+ 27 - 5
sites/all/modules/xmlsitemap/xmlsitemap_custom/xmlsitemap_custom.admin.inc

@@ -2,9 +2,12 @@
 
 
 /**
 /**
  * @file
  * @file
- * Administrative page callbacks for the xmlsitemap_custom module.
+ * Administrative page callbacks for the xmlsitemap_custom.
  */
  */
 
 
+/**
+ * List Links.
+ */
 function xmlsitemap_custom_list_links() {
 function xmlsitemap_custom_list_links() {
   $header = array(
   $header = array(
     'loc' => array('data' => t('Location'), 'field' => 'loc', 'sort' => 'asc'),
     'loc' => array('data' => t('Location'), 'field' => 'loc', 'sort' => 'asc'),
@@ -62,6 +65,9 @@ function xmlsitemap_custom_list_links() {
   return $build;
   return $build;
 }
 }
 
 
+/**
+ * Edit Link Form.
+ */
 function xmlsitemap_custom_edit_link_form($form, &$form_state, $link = array()) {
 function xmlsitemap_custom_edit_link_form($form, &$form_state, $link = array()) {
   module_load_include('inc', 'xmlsitemap', 'xmlsitemap.admin');
   module_load_include('inc', 'xmlsitemap', 'xmlsitemap.admin');
   _xmlsitemap_set_breadcrumb('admin/config/search/xmlsitemap/custom');
   _xmlsitemap_set_breadcrumb('admin/config/search/xmlsitemap/custom');
@@ -116,7 +122,7 @@ function xmlsitemap_custom_edit_link_form($form, &$form_state, $link = array())
   );
   );
 
 
   $form['actions'] = array(
   $form['actions'] = array(
-    '#type' => 'actions'
+    '#type' => 'actions',
   );
   );
   $form['actions']['submit'] = array(
   $form['actions']['submit'] = array(
     '#type' => 'submit',
     '#type' => 'submit',
@@ -131,6 +137,9 @@ function xmlsitemap_custom_edit_link_form($form, &$form_state, $link = array())
   return $form;
   return $form;
 }
 }
 
 
+/**
+ * Edit Link Form Validate.
+ */
 function xmlsitemap_custom_edit_link_form_validate($form, &$form_state) {
 function xmlsitemap_custom_edit_link_form_validate($form, &$form_state) {
   $link = &$form_state['values'];
   $link = &$form_state['values'];
 
 
@@ -143,12 +152,16 @@ function xmlsitemap_custom_edit_link_form_validate($form, &$form_state) {
   $menu_item = menu_get_item($link['loc']);
   $menu_item = menu_get_item($link['loc']);
   xmlsitemap_restore_user();
   xmlsitemap_restore_user();
 
 
-  // Since the menu item access results are cached, manually check the current path.
+  // Since the menu item access results are cached, manually check the current
+  // path.
   if ($menu_item && strpos($link['loc'], 'admin/config/search/xmlsitemap/custom') === 0 && !user_access('administer xmlsitemap', drupal_anonymous_user())) {
   if ($menu_item && strpos($link['loc'], 'admin/config/search/xmlsitemap/custom') === 0 && !user_access('administer xmlsitemap', drupal_anonymous_user())) {
     $menu_item['access'] = FALSE;
     $menu_item['access'] = FALSE;
   }
   }
 
 
-  if (db_query_range("SELECT 1 FROM {xmlsitemap} WHERE type <> 'custom' AND loc = :loc AND status = 1 AND access = 1 AND language IN (:languages)", 0, 1, array(':loc' => $link['loc'], ':languages' => array(LANGUAGE_NONE, $link['language'])))->fetchField()) {
+  if (db_query_range("SELECT 1 FROM {xmlsitemap} WHERE type <> 'custom' AND loc = :loc AND status = 1 AND access = 1 AND language IN (:languages)", 0, 1, array(
+    ':loc' => $link['loc'],
+    ':languages' => array(LANGUAGE_NONE, $link['language']),
+  ))->fetchField()) {
     form_set_error('loc', t('There is already an existing link in the sitemap with the path %link.', array('%link' => $link['loc'])));
     form_set_error('loc', t('There is already an existing link in the sitemap with the path %link.', array('%link' => $link['loc'])));
   }
   }
   elseif (empty($menu_item['access']) && !is_readable('./' . $link['loc'])) {
   elseif (empty($menu_item['access']) && !is_readable('./' . $link['loc'])) {
@@ -158,6 +171,9 @@ function xmlsitemap_custom_edit_link_form_validate($form, &$form_state) {
   }
   }
 }
 }
 
 
+/**
+ * Edit Link Form Submit.
+ */
 function xmlsitemap_custom_edit_link_form_submit($form, &$form_state) {
 function xmlsitemap_custom_edit_link_form_submit($form, &$form_state) {
   $link = $form_state['values'];
   $link = $form_state['values'];
   xmlsitemap_link_save($link);
   xmlsitemap_link_save($link);
@@ -165,8 +181,11 @@ function xmlsitemap_custom_edit_link_form_submit($form, &$form_state) {
   $form_state['redirect'] = 'admin/config/search/xmlsitemap/custom';
   $form_state['redirect'] = 'admin/config/search/xmlsitemap/custom';
 }
 }
 
 
+/**
+ * Delete Link Form.
+ */
 function xmlsitemap_custom_delete_link_form($form, &$form_state, array $link) {
 function xmlsitemap_custom_delete_link_form($form, &$form_state, array $link) {
-  // @todo Remove when http://drupal.org/node/576290 is fixed.
+  // @todo Remove when https://www.drupal.org/node/576290 is fixed.
   _xmlsitemap_set_breadcrumb('admin/config/search/xmlsitemap/custom');
   _xmlsitemap_set_breadcrumb('admin/config/search/xmlsitemap/custom');
 
 
   $form['#link'] = $link;
   $form['#link'] = $link;
@@ -189,6 +208,9 @@ function xmlsitemap_custom_delete_link_form($form, &$form_state, array $link) {
   );
   );
 }
 }
 
 
+/**
+ * Delete Link Form Submit.
+ */
 function xmlsitemap_custom_delete_link_form_submit($form, &$form_state) {
 function xmlsitemap_custom_delete_link_form_submit($form, &$form_state) {
   $link = $form_state['values']['link'];
   $link = $form_state['values']['link'];
   xmlsitemap_link_delete('custom', $link['id']);
   xmlsitemap_link_delete('custom', $link['id']);

+ 3 - 7
sites/all/modules/xmlsitemap/xmlsitemap_custom/xmlsitemap_custom.info

@@ -3,15 +3,11 @@ description = Adds user configurable links to the sitemap.
 package = XML sitemap
 package = XML sitemap
 core = 7.x
 core = 7.x
 dependencies[] = xmlsitemap
 dependencies[] = xmlsitemap
-files[] = xmlsitemap_custom.module
-files[] = xmlsitemap_custom.admin.inc
-files[] = xmlsitemap_custom.install
 files[] = xmlsitemap_custom.test
 files[] = xmlsitemap_custom.test
 configure = admin/config/search/xmlsitemap/custom
 configure = admin/config/search/xmlsitemap/custom
 
 
-; Information added by Drupal.org packaging script on 2016-05-25
-version = "7.x-2.3"
+; Information added by Drupal.org packaging script on 2018-10-09
+version = "7.x-2.6"
 core = "7.x"
 core = "7.x"
 project = "xmlsitemap"
 project = "xmlsitemap"
-datestamp = "1464191061"
-
+datestamp = "1539120486"

+ 6 - 1
sites/all/modules/xmlsitemap/xmlsitemap_custom/xmlsitemap_custom.module

@@ -1,5 +1,10 @@
 <?php
 <?php
 
 
+/**
+ * @file
+ * Main file for XML sitemap Custom.
+ */
+
 /**
 /**
  * Implements hook_menu().
  * Implements hook_menu().
  */
  */
@@ -42,7 +47,7 @@ function xmlsitemap_custom_menu() {
 /**
 /**
  * Menu load callback; load a custom sitemap link from the {xmlsitemap} table.
  * Menu load callback; load a custom sitemap link from the {xmlsitemap} table.
  *
  *
- * @param $id
+ * @param string $id
  *   The sitemap link ID of the custom link to load.
  *   The sitemap link ID of the custom link to load.
  *
  *
  * @see xmlsitemap_link_load()
  * @see xmlsitemap_link_load()

+ 36 - 11
sites/all/modules/xmlsitemap/xmlsitemap_custom/xmlsitemap_custom.test

@@ -2,10 +2,17 @@
 
 
 /**
 /**
  * @file
  * @file
- * Unit tests for the xmlsitemap_custom module.
+ * Unit tests for the xmlsitemap_custom.
  */
  */
 
 
+/**
+ * Class with Functional Test for XML Sitemap Custom.
+ */
 class XMLSitemapCustomFunctionalTest extends XMLSitemapTestHelper {
 class XMLSitemapCustomFunctionalTest extends XMLSitemapTestHelper {
+
+  /**
+   * Get Info.
+   */
   public static function getInfo() {
   public static function getInfo() {
     return array(
     return array(
       'name' => 'XML sitemap custom interface tests',
       'name' => 'XML sitemap custom interface tests',
@@ -14,7 +21,10 @@ class XMLSitemapCustomFunctionalTest extends XMLSitemapTestHelper {
     );
     );
   }
   }
 
 
-  function setUp($modules = array()) {
+  /**
+   * Setup.
+   */
+  public function setUp($modules = array()) {
     $modules[] = 'xmlsitemap_custom';
     $modules[] = 'xmlsitemap_custom';
     $modules[] = 'path';
     $modules[] = 'path';
     parent::setUp($modules);
     parent::setUp($modules);
@@ -23,7 +33,10 @@ class XMLSitemapCustomFunctionalTest extends XMLSitemapTestHelper {
     $this->drupalLogin($this->admin_user);
     $this->drupalLogin($this->admin_user);
   }
   }
 
 
-  function testCustomLinks() {
+  /**
+   * Test Custom Links.
+   */
+  public function testCustomLinks() {
     // Set a path alias for the node page.
     // Set a path alias for the node page.
     $alias = array('source' => 'system/files', 'alias' => 'public-files');
     $alias = array('source' => 'system/files', 'alias' => 'public-files');
     path_save($alias);
     path_save($alias);
@@ -57,7 +70,12 @@ class XMLSitemapCustomFunctionalTest extends XMLSitemapTestHelper {
     $links = xmlsitemap_link_load_multiple(array('type' => 'custom', 'loc' => 'system/files'));
     $links = xmlsitemap_link_load_multiple(array('type' => 'custom', 'loc' => 'system/files'));
     $this->assertEqual(count($links), 1, t('Custom link saved in the database.'));
     $this->assertEqual(count($links), 1, t('Custom link saved in the database.'));
     $link = reset($links);
     $link = reset($links);
-    $this->assertSitemapLinkValues('custom', $link['id'], array('priority' => 0.5, 'changefreq' => 0, 'access' => 1, 'status' => 1));
+    $this->assertSitemapLinkValues('custom', $link['id'], array(
+      'priority' => 0.5,
+      'changefreq' => 0,
+      'access' => 1,
+      'status' => 1,
+    ));
 
 
     $this->clickLink('Edit');
     $this->clickLink('Edit');
     $edit = array(
     $edit = array(
@@ -66,7 +84,12 @@ class XMLSitemapCustomFunctionalTest extends XMLSitemapTestHelper {
     );
     );
     $this->drupalPost(NULL, $edit, t('Save'));
     $this->drupalPost(NULL, $edit, t('Save'));
     $this->assertText('The custom link for system/files was saved');
     $this->assertText('The custom link for system/files was saved');
-    $this->assertSitemapLinkValues('custom', $link['id'], array('priority' => 0.1, 'changefreq' => XMLSITEMAP_FREQUENCY_ALWAYS, 'access' => 1, 'status' => 1));
+    $this->assertSitemapLinkValues('custom', $link['id'], array(
+      'priority' => 0.1,
+      'changefreq' => XMLSITEMAP_FREQUENCY_ALWAYS,
+      'access' => 1,
+      'status' => 1,
+    ));
 
 
     $this->clickLink('Delete');
     $this->clickLink('Delete');
     $this->drupalPost(NULL, array(), t('Delete'));
     $this->drupalPost(NULL, array(), t('Delete'));
@@ -77,7 +100,7 @@ class XMLSitemapCustomFunctionalTest extends XMLSitemapTestHelper {
   /**
   /**
    * Test adding files as custom links.
    * Test adding files as custom links.
    */
    */
-  function testCustomFileLinks() {
+  public function testCustomFileLinks() {
     // Test an invalid file.
     // Test an invalid file.
     $edit['loc'] = $this->randomName();
     $edit['loc'] = $this->randomName();
     $this->drupalPost('admin/config/search/xmlsitemap/custom/add', $edit, t('Save'));
     $this->drupalPost('admin/config/search/xmlsitemap/custom/add', $edit, t('Save'));
@@ -85,11 +108,12 @@ class XMLSitemapCustomFunctionalTest extends XMLSitemapTestHelper {
     $this->assertNoSitemapLink(array('type' => 'custom', 'loc' => $edit['loc']));
     $this->assertNoSitemapLink(array('type' => 'custom', 'loc' => $edit['loc']));
 
 
     // Test an unaccessible file .
     // Test an unaccessible file .
-    //$edit['loc'] = '.htaccess';
-    //$this->drupalPost('admin/config/search/xmlsitemap/custom/add', $edit, t('Save'));
-    //$this->assertText(t('The custom link @link is either invalid or it cannot be accessed by anonymous users.', array('@link' => $edit['loc'])));
-    //$this->assertNoSitemapLink(array('type' => 'custom', 'loc' => $edit['loc']));
-
+    // @codingStandardsIgnoreStart
+    // $edit['loc'] = '.htaccess';
+    // $this->drupalPost('admin/config/search/xmlsitemap/custom/add', $edit, t('Save'));
+    // $this->assertText(t('The custom link @link is either invalid or it cannot be accessed by anonymous users.', array('@link' => $edit['loc'])));
+    // $this->assertNoSitemapLink(array('type' => 'custom', 'loc' => $edit['loc']));
+    // @codingStandardsIgnoreEnd
     // Test a valid file.
     // Test a valid file.
     $edit['loc'] = 'misc/drupal.js';
     $edit['loc'] = 'misc/drupal.js';
     $this->drupalPost('admin/config/search/xmlsitemap/custom/add', $edit, t('Save'));
     $this->drupalPost('admin/config/search/xmlsitemap/custom/add', $edit, t('Save'));
@@ -104,4 +128,5 @@ class XMLSitemapCustomFunctionalTest extends XMLSitemapTestHelper {
     $links = xmlsitemap_link_load_multiple(array('type' => 'custom', 'loc' => $edit['loc']));
     $links = xmlsitemap_link_load_multiple(array('type' => 'custom', 'loc' => $edit['loc']));
     $this->assertEqual(count($links), 1, t('Custom link saved in the database.'));
     $this->assertEqual(count($links), 1, t('Custom link saved in the database.'));
   }
   }
+
 }
 }

+ 79 - 0
sites/all/modules/xmlsitemap/xmlsitemap_engines/README.txt

@@ -0,0 +1,79 @@
+CONTENTS OF THIS FILE
+---------------------
+
+* Introduction
+* Requirements
+* Recommended modules
+* Installation
+* Configuration
+* Troubleshooting
+* Maintainers
+
+INTRODUCTION
+------------
+
+The XML sitemap engines module, part of the XML sitemap
+(https://www.drupal.org/project/xmlsitemap) package, uploads the sitemap to
+search engines automatically. The XML sitemap module creates a sitemap that
+conforms to the sitemaps.org specification. This helps search engines to more
+intelligently crawl a website and keep their results up to date.
+
+* For a full description of the module visit
+  https://www.drupal.org/documentation/modules/xmlsitemap
+
+* To submit bug reports and feature suggestions, or to track changes visit
+  https://www.drupal.org/project/issues/xmlsitemap
+
+
+REQUIREMENTS
+------------
+
+This module requires the following module:
+
+* XML sitemap - https://www.drupal.org/project/xmlsitemap
+
+
+RECOMMENDED MODULES
+-------------------
+
+* Ctools - https://www.drupal.org/project/ctools
+* RobotsTxt - https://www.drupal.org/project/robotstxt
+* Site Verification - https://www.drupal.org/project/site_verify
+* Browscap - https://www.drupal.org/project/browscap
+* Vertical Tabs - https://www.drupal.org/project/vertical_tabs
+
+
+INSTALLATION
+------------
+
+This is a submodule of the XML sitemap module. Install the XML sitemap module
+as you would normally install a contributed Drupal module. Visit
+https://www.drupal.org/node/895232 for further information.
+
+
+CONFIGURATION
+-------------
+
+1. Install the XML sitemap module.
+2. Enable the XML sitemap module.
+3. To upload sitemaps to the search engines and customize how often the sitemaps
+   should be uploaded, enable the XML sitemap engines module.
+4. After building an XML sitemap, navigate to Administration > Configuration >
+   XML sitemap > Search Engines.
+5. Choose which engines you wish to send the sitemap to by selecting the
+   appropriate checkboxes. Save configuration.
+
+
+TROUBLESHOOTING
+---------------
+
+To verify the sitemap’s ownership with search engines, be sure Cron is run
+regularly.
+
+
+MAINTAINERS
+-----------
+* Andrei Mateescu (amateescu) - https://www.drupal.org/u/amateescu
+* Dave Reid - https://www.drupal.org/u/dave-reid
+* Juampy NR (juampynr) - https://www.drupal.org/u/juampynr
+* Tasya Rukmana (tadityar) - https://www.drupal.org/u/tadityar

+ 86 - 11
sites/all/modules/xmlsitemap/xmlsitemap_engines/tests/xmlsitemap_engines.test

@@ -5,9 +5,25 @@
  * Tests for the xmlsitemap_engines module.
  * Tests for the xmlsitemap_engines module.
  */
  */
 
 
+/**
+ * Functional Test.
+ *
+ * @codingStandardsIgnoreStart
+ */
 class XMLSitemapEnginesFunctionalTest extends XMLSitemapTestHelper {
 class XMLSitemapEnginesFunctionalTest extends XMLSitemapTestHelper {
+
+  /**
+   * Submit URL.
+   *
+   * @var string
+   */
   protected $submit_url;
   protected $submit_url;
 
 
+  /**
+   * Get Info.
+   *
+   * @codingStandardsIgnoreEnd
+   */
   public static function getInfo() {
   public static function getInfo() {
     return array(
     return array(
       'name' => 'XML sitemap engines functional tests',
       'name' => 'XML sitemap engines functional tests',
@@ -16,7 +32,10 @@ class XMLSitemapEnginesFunctionalTest extends XMLSitemapTestHelper {
     );
     );
   }
   }
 
 
-  function setUp($modules = array()) {
+  /**
+   * Setup.
+   */
+  public function setUp($modules = array()) {
     $modules[] = 'xmlsitemap_engines';
     $modules[] = 'xmlsitemap_engines';
     $modules[] = 'xmlsitemap_engines_test';
     $modules[] = 'xmlsitemap_engines_test';
     parent::setUp($modules);
     parent::setUp($modules);
@@ -32,7 +51,10 @@ class XMLSitemapEnginesFunctionalTest extends XMLSitemapTestHelper {
     $this->submit_url = url('ping', array('absolute' => TRUE, 'query' => array('sitemap' => ''))) . '[sitemap]';
     $this->submit_url = url('ping', array('absolute' => TRUE, 'query' => array('sitemap' => ''))) . '[sitemap]';
   }
   }
 
 
-  function submitEngines() {
+  /**
+   * Submit Engines.
+   */
+  public function submitEngines() {
     variable_set('xmlsitemap_engines_submit_last', REQUEST_TIME - 10000);
     variable_set('xmlsitemap_engines_submit_last', REQUEST_TIME - 10000);
     variable_set('xmlsitemap_generated_last', REQUEST_TIME - 100);
     variable_set('xmlsitemap_generated_last', REQUEST_TIME - 100);
     variable_set('xmlsitemap_engines_minimum_lifetime', 0);
     variable_set('xmlsitemap_engines_minimum_lifetime', 0);
@@ -40,14 +62,23 @@ class XMLSitemapEnginesFunctionalTest extends XMLSitemapTestHelper {
     $this->assertTrue(variable_get('xmlsitemap_engines_submit_last', 0) > (REQUEST_TIME - 100), 'Submitted the sitemaps to search engines.');
     $this->assertTrue(variable_get('xmlsitemap_engines_submit_last', 0) > (REQUEST_TIME - 100), 'Submitted the sitemaps to search engines.');
   }
   }
 
 
-  function testPrepareURL() {
+  /**
+   * Test Prepare URL.
+   *
+   * @codingStandardsIgnoreStart
+   */
+  public function testPrepareURL() {
+    // @codingStandardsIgnoreEnd
     $sitemap = 'http://example.com/sitemap.xml';
     $sitemap = 'http://example.com/sitemap.xml';
     $input = 'http://example.com/ping?sitemap=[sitemap]&foo=bar';
     $input = 'http://example.com/ping?sitemap=[sitemap]&foo=bar';
     $output = 'http://example.com/ping?sitemap=http://example.com/sitemap.xml&foo=bar';
     $output = 'http://example.com/ping?sitemap=http://example.com/sitemap.xml&foo=bar';
     $this->assertEqual(xmlsitemap_engines_prepare_url($input, $sitemap), $output);
     $this->assertEqual(xmlsitemap_engines_prepare_url($input, $sitemap), $output);
   }
   }
 
 
-  function testSubmitSitemaps() {
+  /**
+   * Test Submit Sitemaps.
+   */
+  public function testSubmitSitemaps() {
     $sitemaps = array();
     $sitemaps = array();
     $sitemap = new stdClass();
     $sitemap = new stdClass();
     $sitemap->uri = array(
     $sitemap->uri = array(
@@ -63,11 +94,26 @@ class XMLSitemapEnginesFunctionalTest extends XMLSitemapTestHelper {
     $sitemaps[] = $sitemap;
     $sitemaps[] = $sitemap;
     xmlsitemap_engines_submit_sitemaps($this->submit_url, $sitemaps);
     xmlsitemap_engines_submit_sitemaps($this->submit_url, $sitemaps);
 
 
-    $this->assertWatchdogMessage(array('type' => 'xmlsitemap', 'message' => 'Recieved ping for @sitemap.', 'variables' => array('@sitemap' => 'http://example.com/sitemap.xml')));
-    $this->assertWatchdogMessage(array('type' => 'xmlsitemap', 'message' => 'Recieved ping for @sitemap.', 'variables' => array('@sitemap' => 'http://example.com/sitemap-2.xml')));
+    $this->assertWatchdogMessage(array(
+      'type' => 'xmlsitemap',
+      'message' => 'Recieved ping for @sitemap.',
+      'variables' => array(
+        '@sitemap' => 'http://example.com/sitemap.xml',
+      ),
+    ));
+    $this->assertWatchdogMessage(array(
+      'type' => 'xmlsitemap',
+      'message' => 'Recieved ping for @sitemap.',
+      'variables' => array(
+        '@sitemap' => 'http://example.com/sitemap-2.xml',
+      ),
+    ));
   }
   }
 
 
-  function testPing() {
+  /**
+   * Test Ping.
+   */
+  public function testPing() {
     $edit = array('xmlsitemap_engines_engines[simpletest]' => TRUE);
     $edit = array('xmlsitemap_engines_engines[simpletest]' => TRUE);
     $this->drupalPost('admin/config/search/xmlsitemap/engines', $edit, t('Save configuration'));
     $this->drupalPost('admin/config/search/xmlsitemap/engines', $edit, t('Save configuration'));
     $this->assertText(t('The configuration options have been saved.'));
     $this->assertText(t('The configuration options have been saved.'));
@@ -77,7 +123,13 @@ class XMLSitemapEnginesFunctionalTest extends XMLSitemapTestHelper {
     $this->assertWatchdogMessage(array('type' => 'xmlsitemap', 'message' => 'Recieved ping for @sitemap.'));
     $this->assertWatchdogMessage(array('type' => 'xmlsitemap', 'message' => 'Recieved ping for @sitemap.'));
   }
   }
 
 
-  function testCustomURL() {
+  /**
+   * Test Custom URL.
+   *
+   * @codingStandardsIgnoreStart
+   */
+  public function testCustomURL() {
+    // @codingStandardsIgnoreEnd
     $edit = array('xmlsitemap_engines_custom_urls' => 'an-invalid-url');
     $edit = array('xmlsitemap_engines_custom_urls' => 'an-invalid-url');
     $this->drupalPost('admin/config/search/xmlsitemap/engines', $edit, t('Save configuration'));
     $this->drupalPost('admin/config/search/xmlsitemap/engines', $edit, t('Save configuration'));
     $this->assertText('Invalid URL an-invalid-url.');
     $this->assertText('Invalid URL an-invalid-url.');
@@ -89,7 +141,14 @@ class XMLSitemapEnginesFunctionalTest extends XMLSitemapTestHelper {
     $this->assertText(t('The configuration options have been saved.'));
     $this->assertText(t('The configuration options have been saved.'));
 
 
     $this->submitEngines();
     $this->submitEngines();
-    $this->assertWatchdogMessage(array('type' => 'xmlsitemap', 'message' => 'Submitted the sitemap to %url and received response @code.', 'variables' => array('%url' => $url, '@code' => '404')));
+    $this->assertWatchdogMessage(array(
+      'type' => 'xmlsitemap',
+      'message' => 'Submitted the sitemap to %url and received response @code.',
+      'variables' => array(
+        '%url' => $url,
+        '@code' => '404',
+      ),
+    ));
     $this->assertWatchdogMessage(array('type' => 'xmlsitemap', 'message' => 'No valid sitemap parameter provided.'));
     $this->assertWatchdogMessage(array('type' => 'xmlsitemap', 'message' => 'No valid sitemap parameter provided.'));
     $this->assertWatchdogMessage(array('type' => 'page not found', 'message' => 'ping'));
     $this->assertWatchdogMessage(array('type' => 'page not found', 'message' => 'ping'));
 
 
@@ -99,7 +158,23 @@ class XMLSitemapEnginesFunctionalTest extends XMLSitemapTestHelper {
 
 
     $this->submitEngines();
     $this->submitEngines();
     $url = xmlsitemap_engines_prepare_url($this->submit_url, url('sitemap.xml', array('absolute' => TRUE)));
     $url = xmlsitemap_engines_prepare_url($this->submit_url, url('sitemap.xml', array('absolute' => TRUE)));
-    $this->assertWatchdogMessage(array('type' => 'xmlsitemap', 'message' => 'Submitted the sitemap to %url and received response @code.', 'variables' => array('%url' => $url, '@code' => '200')));
-    $this->assertWatchdogMessage(array('type' => 'xmlsitemap', 'message' => 'Recieved ping for @sitemap.', 'variables' => array('@sitemap' => url('sitemap.xml', array('absolute' => TRUE)))));
+    $this->assertWatchdogMessage(array(
+      'type' => 'xmlsitemap',
+      'message' => 'Submitted the sitemap to %url and received response @code.',
+      'variables' => array(
+        '%url' => $url,
+        '@code' => '200',
+      ),
+    ));
+    $this->assertWatchdogMessage(array(
+      'type' => 'xmlsitemap',
+      'message' => 'Recieved ping for @sitemap.',
+      'variables' => array(
+        '@sitemap' => url('sitemap.xml', array(
+          'absolute' => TRUE,
+        )),
+      ),
+    ));
   }
   }
+
 }
 }

+ 3 - 6
sites/all/modules/xmlsitemap/xmlsitemap_engines/tests/xmlsitemap_engines_test.info

@@ -2,13 +2,10 @@ name = XML sitemap engines test
 description = Support module for XML sitemap engines testing.
 description = Support module for XML sitemap engines testing.
 package = Testing
 package = Testing
 core = 7.x
 core = 7.x
-files[] = xmlsitemap_engines_test.module
-version = VERSION
 hidden = TRUE
 hidden = TRUE
 
 
-; Information added by Drupal.org packaging script on 2016-05-25
-version = "7.x-2.3"
+; Information added by Drupal.org packaging script on 2018-10-09
+version = "7.x-2.6"
 core = "7.x"
 core = "7.x"
 project = "xmlsitemap"
 project = "xmlsitemap"
-datestamp = "1464191061"
-
+datestamp = "1539120486"

+ 9 - 0
sites/all/modules/xmlsitemap/xmlsitemap_engines/tests/xmlsitemap_engines_test.module

@@ -1,11 +1,17 @@
 <?php
 <?php
 
 
+/**
+ * @file
+ * Unit tests for the XML sitemap engines project.
+ */
+
 /**
 /**
  * Implements hook_menu().
  * Implements hook_menu().
  */
  */
 function xmlsitemap_engines_test_menu() {
 function xmlsitemap_engines_test_menu() {
   $items['ping'] = array(
   $items['ping'] = array(
     'page callback' => 'xmlsitemap_engines_test_pinged',
     'page callback' => 'xmlsitemap_engines_test_pinged',
+    // @codingStandardsIgnoreLine
     'access callback' => TRUE,
     'access callback' => TRUE,
     'type' => MENU_CALLBACK,
     'type' => MENU_CALLBACK,
   );
   );
@@ -30,6 +36,9 @@ function xmlsitemap_engines_test_xmlsitemap_engine_info_alter(&$engines) {
   $engines['simpletest']['url'] = url('ping', array('absolute' => TRUE, 'query' => array('sitemap' => ''))) . '[sitemap]';
   $engines['simpletest']['url'] = url('ping', array('absolute' => TRUE, 'query' => array('sitemap' => ''))) . '[sitemap]';
 }
 }
 
 
+/**
+ * Test pinged.
+ */
 function xmlsitemap_engines_test_pinged() {
 function xmlsitemap_engines_test_pinged() {
   if (empty($_GET['sitemap']) || !valid_url($_GET['sitemap'])) {
   if (empty($_GET['sitemap']) || !valid_url($_GET['sitemap'])) {
     watchdog('xmlsitemap', 'No valid sitemap parameter provided.', array(), WATCHDOG_WARNING);
     watchdog('xmlsitemap', 'No valid sitemap parameter provided.', array(), WATCHDOG_WARNING);

+ 19 - 2
sites/all/modules/xmlsitemap/xmlsitemap_engines/xmlsitemap_engines.admin.inc

@@ -26,7 +26,19 @@ function xmlsitemap_engines_settings_form() {
   $form['xmlsitemap_engines_minimum_lifetime'] = array(
   $form['xmlsitemap_engines_minimum_lifetime'] = array(
     '#type' => 'select',
     '#type' => 'select',
     '#title' => t('Do not submit more often than every'),
     '#title' => t('Do not submit more often than every'),
-    '#options' => drupal_map_assoc(array(3600, 10800, 21600, 32400, 43200, 86400, 172800, 259200, 604800, 604800 * 2, 604800 * 4), 'format_interval'),
+    '#options' => drupal_map_assoc(array(
+      3600,
+      10800,
+      21600,
+      32400,
+      43200,
+      86400,
+      172800,
+      259200,
+      604800,
+      604800 * 2,
+      604800 * 4,
+    ), 'format_interval'),
     '#default_value' => variable_get('xmlsitemap_engines_minimum_lifetime', 86400),
     '#default_value' => variable_get('xmlsitemap_engines_minimum_lifetime', 86400),
   );
   );
   $form['xmlsitemap_engines_submit_updated'] = array(
   $form['xmlsitemap_engines_submit_updated'] = array(
@@ -37,7 +49,12 @@ function xmlsitemap_engines_settings_form() {
   $form['xmlsitemap_engines_custom_urls'] = array(
   $form['xmlsitemap_engines_custom_urls'] = array(
     '#type' => 'textarea',
     '#type' => 'textarea',
     '#title' => t('Custom submission URLs'),
     '#title' => t('Custom submission URLs'),
-    '#description' => t('Enter one URL per line. The token [sitemap] will be replaced with the URL to your sitemap. For example: %example-before would become %example-after.', array('%example-before' => 'http://example.com/ping?[sitemap]', '%example-after' => xmlsitemap_engines_prepare_url('http://example.com/ping?[sitemap]', url('sitemap.xml', array('absolute' => TRUE))))),
+    '#description' => t('Enter one URL per line. The token [sitemap] will be replaced with the URL to your sitemap. For example: %example-before would become %example-after.', array(
+      '%example-before' => 'http://example.com/ping?[sitemap]',
+      '%example-after' => xmlsitemap_engines_prepare_url('http://example.com/ping?[sitemap]', url('sitemap.xml', array(
+        'absolute' => TRUE,
+      ))),
+    )),
     '#default_value' => variable_get('xmlsitemap_engines_custom_urls', ''),
     '#default_value' => variable_get('xmlsitemap_engines_custom_urls', ''),
     '#rows' => 2,
     '#rows' => 2,
     '#wysiwyg' => FALSE,
     '#wysiwyg' => FALSE,

+ 1 - 1
sites/all/modules/xmlsitemap/xmlsitemap_engines/xmlsitemap_engines.api.php

@@ -16,7 +16,7 @@
 function hook_xmlsitemap_engine_info() {
 function hook_xmlsitemap_engine_info() {
   $engines['example'] = array(
   $engines['example'] = array(
     'name' => t('Example search engine'),
     'name' => t('Example search engine'),
-    'url' => 'http://example.com/ping?sitemap=[sitemap]'
+    'url' => 'http://example.com/ping?sitemap=[sitemap]',
   );
   );
   return $engines;
   return $engines;
 }
 }

+ 3 - 7
sites/all/modules/xmlsitemap/xmlsitemap_engines/xmlsitemap_engines.info

@@ -3,16 +3,12 @@ description = Submit the sitemap to search engines.
 package = XML sitemap
 package = XML sitemap
 core = 7.x
 core = 7.x
 dependencies[] = xmlsitemap
 dependencies[] = xmlsitemap
-files[] = xmlsitemap_engines.module
-files[] = xmlsitemap_engines.admin.inc
-files[] = xmlsitemap_engines.install
 files[] = tests/xmlsitemap_engines.test
 files[] = tests/xmlsitemap_engines.test
 recommends[] = site_verify
 recommends[] = site_verify
 configure = admin/config/search/xmlsitemap/engines
 configure = admin/config/search/xmlsitemap/engines
 
 
-; Information added by Drupal.org packaging script on 2016-05-25
-version = "7.x-2.3"
+; Information added by Drupal.org packaging script on 2018-10-09
+version = "7.x-2.6"
 core = "7.x"
 core = "7.x"
 project = "xmlsitemap"
 project = "xmlsitemap"
-datestamp = "1464191061"
-
+datestamp = "1539120486"

+ 36 - 24
sites/all/modules/xmlsitemap/xmlsitemap_engines/xmlsitemap_engines.module

@@ -1,5 +1,10 @@
 <?php
 <?php
 
 
+/**
+ * @file
+ * Main file for XML sitemap engines.
+ */
+
 /**
 /**
  * Implements hook_hook_info().
  * Implements hook_hook_info().
  */
  */
@@ -21,7 +26,7 @@ function xmlsitemap_engines_help($path, $arg) {
   switch ($path) {
   switch ($path) {
     case 'admin/config/search/xmlsitemap/engines':
     case 'admin/config/search/xmlsitemap/engines':
       if (!module_exists('site_verify')) {
       if (!module_exists('site_verify')) {
-        $output .= '<p>' . t('In order to verify site ownership with the search engines listed below, it is highly recommended to download and install the <a href="@site-verify">Site verification module</a>.', array('@site-verify' => 'http://drupal.org/project/site_verify')) . '</p>';
+        $output .= '<p>' . t('In order to verify site ownership with the search engines listed below, it is highly recommended to download and install the <a href="@site-verify">Site verification module</a>.', array('@site-verify' => 'https://www.drupal.org/project/site_verify')) . '</p>';
       }
       }
       break;
       break;
   }
   }
@@ -41,12 +46,13 @@ function xmlsitemap_engines_menu() {
     'type' => MENU_LOCAL_TASK,
     'type' => MENU_LOCAL_TASK,
     'file' => 'xmlsitemap_engines.admin.inc',
     'file' => 'xmlsitemap_engines.admin.inc',
   );
   );
-  //$items['admin/config/search/xmlsitemap/engines/submit'] = array(
-  //  'page callback' => 'xmlsitemap_engines_submit',
-  //  'access callback' => 'xmlsitemap_engines_submit_access',
-  //  'type' => MENU_CALLBACK,
-  //);
-
+  // @code
+  // $items['admin/config/search/xmlsitemap/engines/submit'] = array(
+  //   'page callback' => 'xmlsitemap_engines_submit',
+  //   'access callback' => 'xmlsitemap_engines_submit_access',
+  //   'type' => MENU_CALLBACK,
+  // );
+  // @endcode
   return $items;
   return $items;
 }
 }
 
 
@@ -59,6 +65,9 @@ function xmlsitemap_engines_cron() {
   }
   }
 }
 }
 
 
+/**
+ * Check if can submit.
+ */
 function xmlsitemap_engines_can_submit() {
 function xmlsitemap_engines_can_submit() {
   // Skip if the site is offline since search engines will not be able to
   // Skip if the site is offline since search engines will not be able to
   // access the site's content.
   // access the site's content.
@@ -73,16 +82,21 @@ function xmlsitemap_engines_can_submit() {
   return TRUE;
   return TRUE;
 }
 }
 
 
+/**
+ * Submit access.
+ */
 function xmlsitemap_engines_submit_access() {
 function xmlsitemap_engines_submit_access() {
   if (!xmlsitemap_engines_can_submit()) {
   if (!xmlsitemap_engines_can_submit()) {
     return FALSE;
     return FALSE;
   }
   }
 
 
   // Allow manual submissions to run.
   // Allow manual submissions to run.
-  //if ($_GET['q'] == 'admin/config/search/xmlsitemap/engines/submit' && user_access('administer xmlsitemap')) {
-  //  return TRUE;
-  //}
-
+  // @code
+  // @codingStandardsIgnoreLine
+  // if ($_GET['q'] == 'admin/config/search/xmlsitemap/engines/submit' && user_access('administer xmlsitemap')) {
+  //   return TRUE;
+  // }
+  // @endcode
   $submit_updated = variable_get('xmlsitemap_engines_submit_updated', TRUE);
   $submit_updated = variable_get('xmlsitemap_engines_submit_updated', TRUE);
   $submitted_last = variable_get('xmlsitemap_engines_submit_last', 0);
   $submitted_last = variable_get('xmlsitemap_engines_submit_last', 0);
   $minimum_lifetime = variable_get('xmlsitemap_engines_minimum_lifetime', 86400);
   $minimum_lifetime = variable_get('xmlsitemap_engines_minimum_lifetime', 86400);
@@ -103,7 +117,7 @@ function xmlsitemap_engines_submit_access() {
 /**
 /**
  * Submit the sitemaps to all the specified search engines.
  * Submit the sitemaps to all the specified search engines.
  *
  *
- * @param $smids
+ * @param array $smids
  *   An optional array of XML sitemap IDs. If not provided, it will load all
  *   An optional array of XML sitemap IDs. If not provided, it will load all
  *   existing XML sitemaps.
  *   existing XML sitemaps.
  */
  */
@@ -134,9 +148,9 @@ function xmlsitemap_engines_submit_engines(array $smids = array()) {
 /**
 /**
  * Submit the sitemaps to a specific URL.
  * Submit the sitemaps to a specific URL.
  *
  *
- * @param $url
+ * @param string $url
  *   The URL for sitemap submission.
  *   The URL for sitemap submission.
- * @param $sitemaps
+ * @param array $sitemaps
  *   An array of URLs of the sitemaps to submit.
  *   An array of URLs of the sitemaps to submit.
  */
  */
 function xmlsitemap_engines_submit_sitemaps($url, array $sitemaps) {
 function xmlsitemap_engines_submit_sitemaps($url, array $sitemaps) {
@@ -151,9 +165,10 @@ function xmlsitemap_engines_submit_sitemaps($url, array $sitemaps) {
 /**
 /**
  * Replace valid tokens in the URL with their appropriate values.
  * Replace valid tokens in the URL with their appropriate values.
  *
  *
- * @param $url
+ * @param string $url
  *   An un-tokenized URL.
  *   An un-tokenized URL.
- * @return
+ *
+ * @return string
  *   A tokenized URL.
  *   A tokenized URL.
  */
  */
 function xmlsitemap_engines_prepare_url($url, $sitemap) {
 function xmlsitemap_engines_prepare_url($url, $sitemap) {
@@ -163,12 +178,9 @@ function xmlsitemap_engines_prepare_url($url, $sitemap) {
 /**
 /**
  * Returns information about supported search engines.
  * Returns information about supported search engines.
  *
  *
- * @param $engine
+ * @param string $engine
  *   (optional) The engine to return information for. If omitted, information
  *   (optional) The engine to return information for. If omitted, information
  *   for all engines is returned.
  *   for all engines is returned.
- * @param $reset
- *   (optional) Boolean whether to reset the static cache and do nothing. Only
- *   used for tests.
  *
  *
  * @see hook_xmlsitemap_engines_info()
  * @see hook_xmlsitemap_engines_info()
  * @see hook_xmlsitemap_engines_info_alter()
  * @see hook_xmlsitemap_engines_info_alter()
@@ -205,13 +217,13 @@ function xmlsitemap_engines_get_engine_info($engine = NULL) {
 function xmlsitemap_engines_xmlsitemap_engine_info() {
 function xmlsitemap_engines_xmlsitemap_engine_info() {
   $engines['google'] = array(
   $engines['google'] = array(
     'name' => t('Google'),
     'name' => t('Google'),
-    'url' => 'http://www.google.com/webmasters/tools/ping?sitemap=[sitemap]',
-    'help url' => 'http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156184',
+    'url' => 'https://www.google.com/webmasters/tools/ping?sitemap=[sitemap]',
+    'help url' => 'https://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156184',
   );
   );
   $engines['bing'] = array(
   $engines['bing'] = array(
     'name' => t('Bing'),
     'name' => t('Bing'),
-    'url' => 'http://www.bing.com/webmaster/ping.aspx?siteMap=[sitemap]',
-    'help url' => 'http://www.bing.com/webmaster',
+    'url' => 'https://www.bing.com/webmaster/ping.aspx?siteMap=[sitemap]',
+    'help url' => 'https://www.bing.com/webmaster',
   );
   );
   return $engines;
   return $engines;
 }
 }

+ 3 - 5
sites/all/modules/xmlsitemap/xmlsitemap_i18n/xmlsitemap_i18n.info

@@ -4,12 +4,10 @@ package = XML sitemap
 core = 7.x
 core = 7.x
 dependencies[] = xmlsitemap
 dependencies[] = xmlsitemap
 dependencies[] = i18n
 dependencies[] = i18n
-files[] = xmlsitemap_i18n.module
 files[] = xmlsitemap_i18n.test
 files[] = xmlsitemap_i18n.test
 
 
-; Information added by Drupal.org packaging script on 2016-05-25
-version = "7.x-2.3"
+; Information added by Drupal.org packaging script on 2018-10-09
+version = "7.x-2.6"
 core = "7.x"
 core = "7.x"
 project = "xmlsitemap"
 project = "xmlsitemap"
-datestamp = "1464191061"
-
+datestamp = "1539120486"

+ 11 - 1
sites/all/modules/xmlsitemap/xmlsitemap_i18n/xmlsitemap_i18n.module

@@ -1,5 +1,10 @@
 <?php
 <?php
 
 
+/**
+ * @file
+ * Main file for XML sitemap i18n.
+ */
+
 /**
 /**
  * Implements hook_xmlsitemap_context_info().
  * Implements hook_xmlsitemap_context_info().
  */
  */
@@ -88,14 +93,18 @@ function xmlsitemap_i18n_query_xmlsitemap_generate_alter(QueryAlterableInterface
       // Current language and language neutral.
       // Current language and language neutral.
       $query->condition('x.language', array($current, LANGUAGE_NONE));
       $query->condition('x.language', array($current, LANGUAGE_NONE));
       break;
       break;
+
     case 'mixed':
     case 'mixed':
-      // Mixed current language (if available) or default language (if not) and language neutral.
+      // Mixed current language (if available) or default language (if not) and
+      // language neutral.
       $query->condition('x.language', array($current, $default, LANGUAGE_NONE));
       $query->condition('x.language', array($current, $default, LANGUAGE_NONE));
       break;
       break;
+
     case 'default':
     case 'default':
       // Only default language and language neutral.
       // Only default language and language neutral.
       $query->condition('x.language', array($default, LANGUAGE_NONE));
       $query->condition('x.language', array($default, LANGUAGE_NONE));
       break;
       break;
+
     case 'strict':
     case 'strict':
       // Only current language (for nodes), simple for all other types.
       // Only current language (for nodes), simple for all other types.
       $node_condition = db_and();
       $node_condition = db_and();
@@ -109,6 +118,7 @@ function xmlsitemap_i18n_query_xmlsitemap_generate_alter(QueryAlterableInterface
       $condition->condition($normal_condition);
       $condition->condition($normal_condition);
       $query->condition($condition);
       $query->condition($condition);
       break;
       break;
+
     case 'off':
     case 'off':
       // All content. No language conditions apply.
       // All content. No language conditions apply.
       break;
       break;

+ 43 - 6
sites/all/modules/xmlsitemap/xmlsitemap_i18n/xmlsitemap_i18n.test

@@ -2,19 +2,29 @@
 
 
 /**
 /**
  * @file
  * @file
- * Unit tests for the xmlsitemap_i18n module.
+ * Unit tests for the xmlsitemap_i18n project.
  */
  */
 
 
 /**
 /**
  * Common base test class for XML sitemap internationalization tests.
  * Common base test class for XML sitemap internationalization tests.
  */
  */
 class XMLSitemapI18nWebTestCase extends XMLSitemapTestHelper {
 class XMLSitemapI18nWebTestCase extends XMLSitemapTestHelper {
+
+  /**
+   * Admin User.
+   *
+   * @var string
+   *
+   * @codingStandardsIgnoreStart
+   */
   protected $admin_user;
   protected $admin_user;
 
 
   /**
   /**
    * Set up an administrative user account and testing keys.
    * Set up an administrative user account and testing keys.
+   *
+   * @codingStandardsIgnoreEnd
    */
    */
-  function setUp($modules = array()) {
+  public function setUp($modules = array()) {
     // Call parent::setUp() allowing test cases to pass further modules.
     // Call parent::setUp() allowing test cases to pass further modules.
     $modules[] = 'locale';
     $modules[] = 'locale';
     $modules[] = 'translation';
     $modules[] = 'translation';
@@ -29,7 +39,8 @@ class XMLSitemapI18nWebTestCase extends XMLSitemapTestHelper {
     variable_set('language_negotiation', LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX);
     variable_set('language_negotiation', LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX);
 
 
     // Create the two different language-context sitemaps.
     // Create the two different language-context sitemaps.
-    db_query("DELETE FROM {xmlsitemap_sitemap}");
+    db_delete('xmlsitemap_sitemap')->execute();
+
     $sitemap = new stdClass();
     $sitemap = new stdClass();
     $sitemap->context = array('language' => 'en');
     $sitemap->context = array('language' => 'en');
     xmlsitemap_sitemap_save($sitemap);
     xmlsitemap_sitemap_save($sitemap);
@@ -37,9 +48,17 @@ class XMLSitemapI18nWebTestCase extends XMLSitemapTestHelper {
     $sitemap->context = array('language' => 'fr');
     $sitemap->context = array('language' => 'fr');
     xmlsitemap_sitemap_save($sitemap);
     xmlsitemap_sitemap_save($sitemap);
   }
   }
+
 }
 }
 
 
+/**
+ * I18n Test.
+ */
 class XMLSitemapI18nTest extends XMLSitemapI18nWebTestCase {
 class XMLSitemapI18nTest extends XMLSitemapI18nWebTestCase {
+
+  /**
+   * Get Info.
+   */
   public static function getInfo() {
   public static function getInfo() {
     return array(
     return array(
       'name' => 'XML sitemap i18n tests',
       'name' => 'XML sitemap i18n tests',
@@ -49,7 +68,10 @@ class XMLSitemapI18nTest extends XMLSitemapI18nWebTestCase {
     );
     );
   }
   }
 
 
-  function testLanguageSelection() {
+  /**
+   * Language Selection.
+   */
+  public function testLanguageSelection() {
     // Create our three different language nodes.
     // Create our three different language nodes.
     $node = $this->addSitemapLink(array('type' => 'node', 'language' => LANGUAGE_NONE));
     $node = $this->addSitemapLink(array('type' => 'node', 'language' => LANGUAGE_NONE));
     $node_en = $this->addSitemapLink(array('type' => 'node', 'language' => 'en'));
     $node_en = $this->addSitemapLink(array('type' => 'node', 'language' => 'en'));
@@ -104,9 +126,17 @@ class XMLSitemapI18nTest extends XMLSitemapI18nWebTestCase {
     $this->assertRawSitemapLinks($node_fr, $link, $link_fr);
     $this->assertRawSitemapLinks($node_fr, $link, $link_fr);
     $this->assertNoRawSitemapLinks($node, $node_en, $link_en);
     $this->assertNoRawSitemapLinks($node, $node_en, $link_en);
   }
   }
+
 }
 }
 
 
+/**
+ * Node Test.
+ */
 class XMLSitemapI18nNodeTest extends XMLSitemapI18nWebTestCase {
 class XMLSitemapI18nNodeTest extends XMLSitemapI18nWebTestCase {
+
+  /**
+   * Get Info.
+   */
   public static function getInfo() {
   public static function getInfo() {
     return array(
     return array(
       'name' => 'XML sitemap i18n node tests',
       'name' => 'XML sitemap i18n node tests',
@@ -116,7 +146,10 @@ class XMLSitemapI18nNodeTest extends XMLSitemapI18nWebTestCase {
     );
     );
   }
   }
 
 
-  function setUp($modules = array()) {
+  /**
+   * Setup.
+   */
+  public function setUp($modules = array()) {
     $modules[] = 'xmlsitemap_node';
     $modules[] = 'xmlsitemap_node';
     parent::setUp($modules);
     parent::setUp($modules);
 
 
@@ -125,7 +158,10 @@ class XMLSitemapI18nNodeTest extends XMLSitemapI18nWebTestCase {
     $this->drupalLogin($this->admin_user);
     $this->drupalLogin($this->admin_user);
   }
   }
 
 
-  function testNodeLanguageData() {
+  /**
+   * Node Language Data.
+   */
+  public function testNodeLanguageData() {
     $node = $this->drupalCreateNode(array());
     $node = $this->drupalCreateNode(array());
 
 
     $this->drupalPost('node/' . $node->nid . '/edit', array('language' => 'en'), t('Save'));
     $this->drupalPost('node/' . $node->nid . '/edit', array('language' => 'en'), t('Save'));
@@ -136,4 +172,5 @@ class XMLSitemapI18nNodeTest extends XMLSitemapI18nWebTestCase {
     $link = $this->assertSitemapLink('node', $node->nid);
     $link = $this->assertSitemapLink('node', $node->nid);
     $this->assertIdentical($link['language'], 'fr');
     $this->assertIdentical($link['language'], 'fr');
   }
   }
+
 }
 }

+ 79 - 0
sites/all/modules/xmlsitemap/xmlsitemap_menu/README.txt

@@ -0,0 +1,79 @@
+CONTENTS OF THIS FILE
+---------------------
+
+* Introduction
+* Requirements
+* Recommended modules
+* Installation
+* Configuration
+* Maintainers
+
+
+INTRODUCTION
+------------
+
+The XML sitemap menu module, part of the XML sitemap
+(https://www.drupal.org/project/xmlsitemap) package, enables menu links to be on
+the site map. The XML sitemap module creates a sitemap that conforms to the
+sitemaps.org specification. This helps search engines to more intelligently
+crawl a website and keep their results up to date.
+
+* For a full description of the module visit
+  https://www.drupal.org/documentation/modules/xmlsitemap
+
+* To submit bug reports and feature suggestions, or to track changes visit
+  https://www.drupal.org/project/issues/xmlsitemap
+
+
+REQUIREMENTS
+------------
+
+This module requires the following module:
+
+* XML sitemap - https://www.drupal.org/project/xmlsitemap
+
+
+RECOMMENDED MODULES
+-------------------
+
+* Ctools - https://www.drupal.org/project/ctools
+* RobotsTxt - https://www.drupal.org/project/robotstxt
+* Site Verification - https://www.drupal.org/project/site_verify
+* Browscap - https://www.drupal.org/project/browscap
+* Vertical Tabs - https://www.drupal.org/project/vertical_tabs
+
+
+INSTALLATION
+------------
+
+This is a submodule of the XML sitemap module. Install the XML sitemap module as
+you would normally install a contributed Drupal module. Visit
+https://www.drupal.org/node/895232 for further information.
+
+
+CONFIGURATION
+-------------
+
+1. Install the XML sitemap module.
+2. Enable the XML sitemap module.
+3. To include menu items in the sitemap, enable the XML sitemap menu submodule.
+4. Navigate to Administration > Configuration > Search > XML Sitemap.
+5. Select the Settings tab and there will be a Menu link field set. Open.
+6. Choose the menu link to be edited. There will now be a XML sitemap horizontal
+   tab. Under "Inclusion" change "Excluded" to become "Included". Select Save.
+7. Once that is all complete, go to Configuration > Search and Metadata > XML
+   Sitemap.
+8. Select the Rebuild Links tab in the upper right.
+9. Select on "Rebuild sitemap" even if the message says that you do not need to.
+10. Now you're taken back to the configuration page which shows you the link to
+    your XML sitemap which you can select and confirm that pages have been
+    added.
+
+
+MAINTAINERS
+-----------
+
+* Andrei Mateescu (amateescu) - https://www.drupal.org/u/amateescu
+* Dave Reid - https://www.drupal.org/u/dave-reid
+* Juampy NR (juampynr) - https://www.drupal.org/u/juampynr
+* Tasya Rukmana (tadityar) - https://www.drupal.org/u/tadityar

+ 3 - 6
sites/all/modules/xmlsitemap/xmlsitemap_menu/xmlsitemap_menu.info

@@ -4,13 +4,10 @@ package = XML sitemap
 core = 7.x
 core = 7.x
 dependencies[] = xmlsitemap
 dependencies[] = xmlsitemap
 dependencies[] = menu
 dependencies[] = menu
-files[] = xmlsitemap_menu.module
-files[] = xmlsitemap_menu.install
 files[] = xmlsitemap_menu.test
 files[] = xmlsitemap_menu.test
 
 
-; Information added by Drupal.org packaging script on 2016-05-25
-version = "7.x-2.3"
+; Information added by Drupal.org packaging script on 2018-10-09
+version = "7.x-2.6"
 core = "7.x"
 core = "7.x"
 project = "xmlsitemap"
 project = "xmlsitemap"
-datestamp = "1464191061"
-
+datestamp = "1539120486"

+ 44 - 18
sites/all/modules/xmlsitemap/xmlsitemap_menu/xmlsitemap_menu.module

@@ -1,5 +1,10 @@
 <?php
 <?php
 
 
+/**
+ * @file
+ * Main file for XML sitemap menu.
+ */
+
 /**
 /**
  * Implements hook_entity_info_alter().
  * Implements hook_entity_info_alter().
  *
  *
@@ -54,6 +59,9 @@ function xmlsitemap_menu_entity_info_alter(&$info) {
         'process callback' => 'xmlsitemap_menu_xmlsitemap_process_menu_links',
         'process callback' => 'xmlsitemap_menu_xmlsitemap_process_menu_links',
       ),
       ),
     );
     );
+    if (!isset($info['menu_link']['bundle label'])) {
+      $info['menu_link']['bundle label'] = t('Menu');
+    }
   }
   }
 }
 }
 
 
@@ -87,7 +95,7 @@ function xmlsitemap_menu_xmlsitemap_index_links($limit) {
 /**
 /**
  * Process menu sitemap links.
  * Process menu sitemap links.
  *
  *
- * @param $mlids
+ * @param array $mlids
  *   An array of menu link IDs.
  *   An array of menu link IDs.
  */
  */
 function xmlsitemap_menu_xmlsitemap_process_menu_links(array $mlids, array $xmlsitemap = array()) {
 function xmlsitemap_menu_xmlsitemap_process_menu_links(array $mlids, array $xmlsitemap = array()) {
@@ -122,19 +130,23 @@ function xmlsitemap_menu_form_menu_edit_menu_alter(&$form, $form_state) {
   xmlsitemap_add_link_bundle_settings($form, $form_state, 'menu_link', $menu);
   xmlsitemap_add_link_bundle_settings($form, $form_state, 'menu_link', $menu);
 }
 }
 
 
-//function xmlsitemap_menu_form_menu_overview_form_alter(&$form, $form_state) {
-//  $form['#submit'][] = 'xmlsitemap_menu_menu_overview_form_submit';
-//}
-//
-//function xmlsitemap_menu_menu_overview_form_submit($form, $form_state) {
-//  $mlids = array();
-//  foreach (element_children($form) as $mlid) {
-//    if (isset($form[$mlid]['#item'])) {
-//      $mlids[] = $form[$mlid]['#item']['mlid'];
-//    }
-//  }
-//  xmlsitemap_menu_xmlsitemap_process_menu_links($mlids);
-//}
+/**
+ * Example functions.
+ *
+ * Function xmlsitemap_menu_form_menu_overview_form_alter(&$form, $form_state) {
+ *  $form['#submit'][] = 'xmlsitemap_menu_menu_overview_form_submit';
+ * }
+ *
+ * Function xmlsitemap_menu_menu_overview_form_submit($form, $form_state) {
+ *  $mlids = array();
+ *  foreach (element_children($form) as $mlid) {
+ *    if (isset($form[$mlid]['#item'])) {
+ *      $mlids[] = $form[$mlid]['#item']['mlid'];
+ *    }
+ *  }
+ *  xmlsitemap_menu_xmlsitemap_process_menu_links($mlids);
+ * }
+ */
 
 
 /**
 /**
  * Implements hook_form_FORM_ID_alter().
  * Implements hook_form_FORM_ID_alter().
@@ -202,8 +214,9 @@ function xmlsitemap_menu_menu_link_insert(array $link) {
  * @see hook_menu_link_alter()
  * @see hook_menu_link_alter()
  */
  */
 function xmlsitemap_menu_menu_link_update(array $link) {
 function xmlsitemap_menu_menu_link_update(array $link) {
-  //$link += array('xmlsitemap' => array());
-  //xmlsitemap_menu_xmlsitemap_process_menu_links(array($link['mlid']), $link['xmlsitemap']);
+  // $link += array('xmlsitemap' => array());
+  // @codingStandardsIgnoreLine
+  // xmlsitemap_menu_xmlsitemap_process_menu_links(array($link['mlid']), $link['xmlsitemap']);.
 }
 }
 
 
 /**
 /**
@@ -213,7 +226,7 @@ function xmlsitemap_menu_menu_link_update(array $link) {
  * hook is not always called if the user does not edit the core menu item
  * hook is not always called if the user does not edit the core menu item
  * fields.
  * fields.
  *
  *
- * @see http://drupal.org/node/1013856
+ * @see https://www.drupal.org/node/1013856
  */
  */
 function xmlsitemap_menu_menu_link_alter(array &$link) {
 function xmlsitemap_menu_menu_link_alter(array &$link) {
   if (!empty($link['mlid'])) {
   if (!empty($link['mlid'])) {
@@ -232,7 +245,7 @@ function xmlsitemap_menu_menu_link_delete(array $link) {
 /**
 /**
  * Create a sitemap link from a menu item.
  * Create a sitemap link from a menu item.
  *
  *
- * @param $menu_item
+ * @param array $menu_item
  *   A loaded menu item.
  *   A loaded menu item.
  */
  */
 function xmlsitemap_menu_create_link(array $menu_item) {
 function xmlsitemap_menu_create_link(array $menu_item) {
@@ -262,6 +275,19 @@ function xmlsitemap_menu_create_link(array $menu_item) {
   $menu_item['xmlsitemap']['access'] = $menu_item['access'] && !$menu_item['external'] && !$menu_item['hidden'];
   $menu_item['xmlsitemap']['access'] = $menu_item['access'] && !$menu_item['external'] && !$menu_item['hidden'];
   $menu_item['xmlsitemap']['language'] = isset($menu_item['options']['langcode']) ? $menu_item['options']['langcode'] : LANGUAGE_NONE;
   $menu_item['xmlsitemap']['language'] = isset($menu_item['options']['langcode']) ? $menu_item['options']['langcode'] : LANGUAGE_NONE;
 
 
+  // Exclude menu items created for nodes that are added by xmlsitemap_node.
+  if ($menu_item['xmlsitemap']['access'] && $menu_item['router_path'] == 'node/%' && module_exists('xmlsitemap_node')) {
+    $node = node_load(substr($menu_item['link_path'], 5));
+    if ($node) {
+      if (empty($node->xmlsitemap)) {
+        xmlsitemap_node_create_link($node);
+      }
+      if ($node->xmlsitemap['status'] && $node->xmlsitemap['access']) {
+        $menu_item['xmlsitemap']['status'] = FALSE;
+      }
+    }
+  }
+
   return $menu_item['xmlsitemap'];
   return $menu_item['xmlsitemap'];
 }
 }
 
 

+ 32 - 4
sites/all/modules/xmlsitemap/xmlsitemap_menu/xmlsitemap_menu.test

@@ -2,13 +2,35 @@
 
 
 /**
 /**
  * @file
  * @file
- * Unit tests for the xmlsitemap_menu module.
+ * Unit tests for the xmlsitemap_menu project..
  */
  */
 
 
+/**
+ * Menu Functional Test.
+ */
 class XMLSitemapMenuFunctionalTest extends XMLSitemapTestHelper {
 class XMLSitemapMenuFunctionalTest extends XMLSitemapTestHelper {
+
+  /**
+   * Normal User.
+   *
+   * @var string
+   *
+   * @codingStandardsIgnoreStart
+   */
   protected $normal_user;
   protected $normal_user;
+
+  /**
+   * Menu Items.
+   *
+   * @var array
+   */
   protected $menu_items = array();
   protected $menu_items = array();
 
 
+  /**
+   * Get Info.
+   *
+   * @codingStandardsIgnoreEnd
+   */
   public static function getInfo() {
   public static function getInfo() {
     return array(
     return array(
       'name' => 'XML sitemap menu',
       'name' => 'XML sitemap menu',
@@ -17,7 +39,10 @@ class XMLSitemapMenuFunctionalTest extends XMLSitemapTestHelper {
     );
     );
   }
   }
 
 
-  function setUp($modules = array()) {
+  /**
+   * Setup.
+   */
+  public function setUp($modules = array()) {
     $modules[] = 'xmlsitemap_menu';
     $modules[] = 'xmlsitemap_menu';
     $modules[] = 'menu';
     $modules[] = 'menu';
     parent::setUp($modules);
     parent::setUp($modules);
@@ -26,7 +51,10 @@ class XMLSitemapMenuFunctionalTest extends XMLSitemapTestHelper {
     $this->normal_user = $this->drupalCreateUser(array('access content'));
     $this->normal_user = $this->drupalCreateUser(array('access content'));
   }
   }
 
 
-  function testMenuSettings() {
+  /**
+   * Menu Settings.
+   */
+  public function testMenuSettings() {
     $this->drupalLogin($this->admin_user);
     $this->drupalLogin($this->admin_user);
 
 
     $edit = array(
     $edit = array(
@@ -36,7 +64,6 @@ class XMLSitemapMenuFunctionalTest extends XMLSitemapTestHelper {
       'xmlsitemap[priority]' => '1.0',
       'xmlsitemap[priority]' => '1.0',
     );
     );
     $this->drupalPost('admin/structure/menu/add', $edit, 'Save');
     $this->drupalPost('admin/structure/menu/add', $edit, 'Save');
-    $menu = menu_load($edit['menu_name']);
 
 
     $this->clickLink('Add link');
     $this->clickLink('Add link');
     $edit = array(
     $edit = array(
@@ -47,4 +74,5 @@ class XMLSitemapMenuFunctionalTest extends XMLSitemapTestHelper {
     );
     );
     $this->drupalPost(NULL, $edit, 'Save');
     $this->drupalPost(NULL, $edit, 'Save');
   }
   }
+
 }
 }

+ 3 - 5
sites/all/modules/xmlsitemap/xmlsitemap_modal/xmlsitemap_modal.info

@@ -4,12 +4,10 @@ package = XML sitemap
 core = 7.x
 core = 7.x
 dependencies[] = xmlsitemap
 dependencies[] = xmlsitemap
 dependencies[] = ctools
 dependencies[] = ctools
-files[] = xmlsitemap_modal.module
 hidden = TRUE
 hidden = TRUE
 
 
-; Information added by Drupal.org packaging script on 2016-05-25
-version = "7.x-2.3"
+; Information added by Drupal.org packaging script on 2018-10-09
+version = "7.x-2.6"
 core = "7.x"
 core = "7.x"
 project = "xmlsitemap"
 project = "xmlsitemap"
-datestamp = "1464191061"
-
+datestamp = "1539120486"

+ 7 - 2
sites/all/modules/xmlsitemap/xmlsitemap_modal/xmlsitemap_modal.module

@@ -1,11 +1,16 @@
 <?php
 <?php
 
 
+/**
+ * @file
+ * Main file for XML sitemap Modal.
+ */
+
 /**
 /**
  * Implements hook_menu_alter().
  * Implements hook_menu_alter().
  */
  */
 function xmlsitemap_modal_menu_alter(&$items) {
 function xmlsitemap_modal_menu_alter(&$items) {
   foreach ($items as $path => $item) {
   foreach ($items as $path => $item) {
-    if (!empty($item['modal']) && strpos($path, '%ctools_js') === FALSE && $item['page callback'] ==='drupal_get_form') {
+    if (!empty($item['modal']) && strpos($path, '%ctools_js') === FALSE && $item['page callback'] === 'drupal_get_form') {
       $items["$path/%ctools_js"] = $item;
       $items["$path/%ctools_js"] = $item;
       $items["$path/%ctools_js"]['page callback'] = 'xmlsitemap_modal_get_form';
       $items["$path/%ctools_js"]['page callback'] = 'xmlsitemap_modal_get_form';
       $items["$path/%ctools_js"]['page arguments'][] = substr_count($path, '/') + 1;
       $items["$path/%ctools_js"]['page arguments'][] = substr_count($path, '/') + 1;
@@ -73,7 +78,7 @@ function xmlsitemap_modal_xmlsitemap_operation_link_alter(array &$link) {
       $link['href'] = trim($link['href'], '/');
       $link['href'] = trim($link['href'], '/');
     }
     }
 
 
-    // @todo Remove when http://drupal.org/node/565808 is fixed.
+    // @todo Remove when https://www.drupal.org/node/565808 is fixed.
     if (substr($link['href'], -4) === 'nojs') {
     if (substr($link['href'], -4) === 'nojs') {
       $link['href'] .= '/';
       $link['href'] .= '/';
     }
     }

+ 81 - 0
sites/all/modules/xmlsitemap/xmlsitemap_node/README.txt

@@ -0,0 +1,81 @@
+CONTENTS OF THIS FILE
+---------------------
+
+* Introduction
+* Requirements
+* Recommended modules
+* Installation
+* Configuration
+* Maintainers
+
+
+INTRODUCTION
+------------
+
+The XML sitemap node module, part of the XML sitemap
+(https://www.drupal.org/project/xmlsitemap) package, enables content nodes to
+be in the sitemap. The XML sitemap module creates a sitemap that conforms to
+the sitemaps.org specification. This helps search engines to more intelligently
+crawl a website and keep their results up to date.
+
+* For a full description of the module visit:
+  https://www.drupal.org/project/xmlsitemap
+
+* To submit bug reports and feature suggestions, or to track changes visit:
+  https://www.drupal.org/project/issues/xmlsitemap
+
+
+REQUIREMENTS
+------------
+
+This module requires the following modules:
+
+* XML sitemap - (https://www.drupal.org/project/xmlsitemap)
+
+
+RECOMMENDED MODULES
+-------------------
+
+* Ctools - (https://www.drupal.org/project/ctools)
+* RobotsTxt - (https://www.drupal.org/project/robotstxt)
+* Site Verification - (https://www.drupal.org/project/site_verify)
+* Browscap - (https://www.drupal.org/project/browscap)
+* Vertical Tabs - (https://www.drupal.org/project/vertical_tabs)
+
+
+INSTALLATION
+------------
+
+* This is a submodule of the XML sitemap module. Install the XML sitemap module
+as you would normally install a contributed Drupal module. Visit
+https://www.drupal.org/node/895232 for further information.
+
+
+CONFIGURATION
+-------------
+
+1. Install the XML sitemap module.
+2. Enable the XML sitemap module.
+3. To include nodes in the sitemap, enable the XML sitemap node submodule.
+4. To add nodes to the sitemap, visit the Edit page of the Content Type which
+   you want to appear on the sitemap.
+5. Select the XML sitemap horizontal tab.
+6. Under "Inclusion" change "Excluded" to become "Included". Save.
+7. If enabled, all content of the specific node type will be included.
+   Individual nodes can be excluded on their specific node edit page.
+8. Once that is all complete, go to Configurations --> Search and Metadata -->
+   XML sitemap.
+9. Select the Rebuild Links tab in the upper right.
+10. Select on "Rebuild sitemap" even if the message says that you do not need
+   to.
+11. Now you're taken back to the config page which shows you the link to your
+    XML sitemap which you can select and confirm that pages have been added.
+
+
+MAINTAINERS
+-----------
+
+* Andrei Mateescu (amateescu) - https://www.drupal.org/u/amateescu
+* Dave Reid - https://www.drupal.org/u/dave-reid
+* Juampy NR (juampynr) - https://www.drupal.org/u/juampynr
+* Tasya Rukmana (tadityar) - https://www.drupal.org/u/tadityar

+ 3 - 6
sites/all/modules/xmlsitemap/xmlsitemap_node/xmlsitemap_node.info

@@ -3,13 +3,10 @@ description = Adds content links to the sitemap.
 package = XML sitemap
 package = XML sitemap
 core = 7.x
 core = 7.x
 dependencies[] = xmlsitemap
 dependencies[] = xmlsitemap
-files[] = xmlsitemap_node.module
-files[] = xmlsitemap_node.install
 files[] = xmlsitemap_node.test
 files[] = xmlsitemap_node.test
 
 
-; Information added by Drupal.org packaging script on 2016-05-25
-version = "7.x-2.3"
+; Information added by Drupal.org packaging script on 2018-10-09
+version = "7.x-2.6"
 core = "7.x"
 core = "7.x"
 project = "xmlsitemap"
 project = "xmlsitemap"
-datestamp = "1464191061"
-
+datestamp = "1539120486"

+ 69 - 23
sites/all/modules/xmlsitemap/xmlsitemap_node/xmlsitemap_node.module

@@ -1,5 +1,10 @@
 <?php
 <?php
 
 
+/**
+ * @file
+ * Default file for XML sitemap node.
+ */
+
 /**
 /**
  * Implements hook_entity_info_alter().
  * Implements hook_entity_info_alter().
  */
  */
@@ -17,7 +22,32 @@ function xmlsitemap_node_entity_info_alter(array &$entity_info) {
  * Process old nodes not found in the {xmlsitemap} table.
  * Process old nodes not found in the {xmlsitemap} table.
  */
  */
 function xmlsitemap_node_cron() {
 function xmlsitemap_node_cron() {
-  xmlsitemap_node_xmlsitemap_index_links(xmlsitemap_var('batch_limit'));
+  $limit = xmlsitemap_var('batch_limit');
+
+  // Process nodes that have been queued in hook_node_update().
+  $queue = DrupalQueue::get('xmlsitemap_node');
+  while ($limit > 0 && $item = $queue->claimItem()) {
+    $limit--;
+    try {
+      $node = node_load($item->data);
+      // The node could have been deleted in the meantime, skip XML sitemap
+      // updates in this case.
+      if ($node) {
+        $link = xmlsitemap_node_create_link($node);
+        xmlsitemap_link_save($link, array($link['type'] => $node));
+      }
+      $queue->deleteItem($item);
+    }
+    catch (Exception $e) {
+      // In case of exception log it and leave the item in the queue
+      // to be processed again later.
+      watchdog_exception('xmlsitemap_node', $e);
+    }
+  }
+
+  // Add nodes that are missing from the {xmlsitemap} table.
+  // This catches nodes that were created prior to this module being enabled.
+  xmlsitemap_node_xmlsitemap_index_links($limit);
 }
 }
 
 
 /**
 /**
@@ -33,14 +63,23 @@ function xmlsitemap_node_xmlsitemap_index_links($limit) {
 /**
 /**
  * Process node sitemap links.
  * Process node sitemap links.
  *
  *
- * @param $nids
+ * @param array $nids
  *   An array of node IDs.
  *   An array of node IDs.
  */
  */
 function xmlsitemap_node_xmlsitemap_process_node_links(array $nids) {
 function xmlsitemap_node_xmlsitemap_process_node_links(array $nids) {
-  $nodes = node_load_multiple($nids);
-  foreach ($nodes as $node) {
-    $link = xmlsitemap_node_create_link($node);
-    xmlsitemap_link_save($link, array($link['type'] => $node));
+  // Load no more than 15 nodes at a time.
+  if (count($nids) >= 1) {
+    $nids_chunks = array_chunk($nids, 15);
+    foreach ($nids_chunks as $chunk) {
+      $nodes = node_load_multiple($chunk);
+      foreach ($nodes as $node) {
+        $link = xmlsitemap_node_create_link($node);
+        xmlsitemap_link_save($link, array($link['type'] => $node));
+      }
+      // Flush each entity from the load cache after processing, to avoid
+      // exceeding PHP memory limits if $nids is large.
+      entity_get_controller('node')->resetCache($chunk);
+    }
   }
   }
 }
 }
 
 
@@ -55,8 +94,15 @@ function xmlsitemap_node_node_insert(stdClass $node) {
  * Implements hook_node_update().
  * Implements hook_node_update().
  */
  */
 function xmlsitemap_node_node_update(stdClass $node) {
 function xmlsitemap_node_node_update(stdClass $node) {
+  // Save a sitemap link with revoked access until the node permissions are
+  // checked in the cron.
   $link = xmlsitemap_node_create_link($node);
   $link = xmlsitemap_node_create_link($node);
-  xmlsitemap_link_save($link, array($link['type'] => $node));
+  xmlsitemap_link_presave($link, array($link['type'] => $node));
+  // Node access can not be accurately determined in hook_node_update() because
+  // node grants have not yet been written to the table, so we defer checking
+  // node access permissions and process the sitemap link during cron.
+  $queue = DrupalQueue::get('xmlsitemap_node');
+  $queue->createItem($node->nid);
 }
 }
 
 
 /**
 /**
@@ -70,7 +116,7 @@ function xmlsitemap_node_node_delete(stdClass $node) {
  * Implements hook_comment_update().
  * Implements hook_comment_update().
  */
  */
 function xmlsitemap_node_comment_update(stdClass $comment) {
 function xmlsitemap_node_comment_update(stdClass $comment) {
-  if ($node = node_load($comment->nid, NULL, TRUE)) {
+  if ($node = entity_load_unchanged('node', $comment->nid)) {
     xmlsitemap_node_node_update($node);
     xmlsitemap_node_node_update($node);
   }
   }
 }
 }
@@ -126,6 +172,8 @@ function xmlsitemap_node_form_node_type_form_alter(array &$form, array $form_sta
 /**
 /**
  * Implements hook_form_alter().
  * Implements hook_form_alter().
  *
  *
+ * @codingStandardsIgnoreLine
+ *
  * Add the XML sitemap individual link options for a node.
  * Add the XML sitemap individual link options for a node.
  *
  *
  * @see xmlsitemap_add_form_link_options()
  * @see xmlsitemap_add_form_link_options()
@@ -140,9 +188,10 @@ function xmlsitemap_node_form_node_form_alter(array &$form, array &$form_state)
 /**
 /**
  * Fetch all the timestamps for when a node was changed.
  * Fetch all the timestamps for when a node was changed.
  *
  *
- * @param $node
+ * @param object $node
  *   A node object.
  *   A node object.
- * @return
+ *
+ * @return array
  *   An array of UNIX timestamp integers.
  *   An array of UNIX timestamp integers.
  */
  */
 function xmlsitemap_node_get_timestamps(stdClass $node) {
 function xmlsitemap_node_get_timestamps(stdClass $node) {
@@ -164,7 +213,7 @@ function xmlsitemap_node_get_timestamps(stdClass $node) {
  *
  *
  * The link will be saved as $node->xmlsitemap.
  * The link will be saved as $node->xmlsitemap.
  *
  *
- * @param $node
+ * @param object $node
  *   A node object.
  *   A node object.
  */
  */
 function xmlsitemap_node_create_link(stdClass $node) {
 function xmlsitemap_node_create_link(stdClass $node) {
@@ -195,11 +244,6 @@ function xmlsitemap_node_create_link(stdClass $node) {
   $node->xmlsitemap['changefreq'] = $node->nid ? xmlsitemap_calculate_changefreq($timestamps) : 0;
   $node->xmlsitemap['changefreq'] = $node->nid ? xmlsitemap_calculate_changefreq($timestamps) : 0;
   $node->xmlsitemap['changecount'] = $node->nid ? count($timestamps) - 1 : 0;
   $node->xmlsitemap['changecount'] = $node->nid ? count($timestamps) - 1 : 0;
 
 
-  // Node access must be reset since it a user may have changed published status, etc.
-  //$access = &drupal_static('node_access');
-  //unset($access[0][$node->nid]);
-  //node_access_acquire_grants($node);
-
   // The following values must always be checked because they are volatile.
   // The following values must always be checked because they are volatile.
   $node->xmlsitemap['loc'] = $uri['path'];
   $node->xmlsitemap['loc'] = $uri['path'];
   $node->xmlsitemap['lastmod'] = count($timestamps) ? max($timestamps) : 0;
   $node->xmlsitemap['lastmod'] = count($timestamps) ? max($timestamps) : 0;
@@ -212,16 +256,18 @@ function xmlsitemap_node_create_link(stdClass $node) {
 /**
 /**
  * Determine whether a user may view the specified node.
  * Determine whether a user may view the specified node.
  *
  *
- * @param $node
+ * @param object $node
  *   The node object on which the operation is to be performed, or node type
  *   The node object on which the operation is to be performed, or node type
  *   (e.g. 'forum') for "create" operation.
  *   (e.g. 'forum') for "create" operation.
- * @param $account
+ * @param object $account
  *   Optional, a user object representing the user for whom the operation is to
  *   Optional, a user object representing the user for whom the operation is to
  *   be performed. Determines access for a user other than the current user.
  *   be performed. Determines access for a user other than the current user.
- * @return
+ *
+ * @return bool
  *   TRUE if the operation may be performed, FALSE otherwise.
  *   TRUE if the operation may be performed, FALSE otherwise.
  *
  *
- * This is for all intesive purposes a copy of Drupal 7's node_access() function.
+ *   This is for all intesive purposes a copy of Drupal 7's node_access()
+ *   function.
  */
  */
 function xmlsitemap_node_view_access($node, $account = NULL) {
 function xmlsitemap_node_view_access($node, $account = NULL) {
   global $user;
   global $user;
@@ -241,8 +287,7 @@ function xmlsitemap_node_view_access($node, $account = NULL) {
 
 
   // $node may be either an object or a node type. Since node types cannot be
   // $node may be either an object or a node type. Since node types cannot be
   // an integer, use either nid or type as the static cache id.
   // an integer, use either nid or type as the static cache id.
-  //$cid = is_object($node) ? $node->nid : $node;
-
+  // $cid = is_object($node) ? $node->nid : $node;
   // If we've already checked access for this node, user and op, return from
   // If we've already checked access for this node, user and op, return from
   // cache.
   // cache.
   if (isset($rights[$account->uid][$node->nid])) {
   if (isset($rights[$account->uid][$node->nid])) {
@@ -294,7 +339,8 @@ function xmlsitemap_node_view_access($node, $account = NULL) {
       $query->condition($nids);
       $query->condition($nids);
       $query->range(0, 1);
       $query->range(0, 1);
 
 
-      // Fetch the node grants and allow other modules to alter them (D7 backport).
+      // Fetch the node grants and allow other modules to alter them
+      // (D7 backport).
       $grants = &drupal_static(__FUNCTION__ . ':grants', array());
       $grants = &drupal_static(__FUNCTION__ . ':grants', array());
       if (!isset($grants[$account->uid][$op])) {
       if (!isset($grants[$account->uid][$op])) {
         // Indicate that this is our special function in the grants.
         // Indicate that this is our special function in the grants.

+ 97 - 17
sites/all/modules/xmlsitemap/xmlsitemap_node/xmlsitemap_node.test

@@ -5,10 +5,30 @@
  * Unit tests for the xmlsitemap_node module.
  * Unit tests for the xmlsitemap_node module.
  */
  */
 
 
+/**
+ * Node Functional Test.
+ */
 class XMLSitemapNodeFunctionalTest extends XMLSitemapTestHelper {
 class XMLSitemapNodeFunctionalTest extends XMLSitemapTestHelper {
+
+  /**
+   * Normal User.
+   *
+   * @var string
+   *
+   * @codingStandardsIgnoreStart
+   */
   protected $normal_user;
   protected $normal_user;
+
+  /**
+   * Nodes.
+   *
+   * @var array
+   */
   protected $nodes = array();
   protected $nodes = array();
 
 
+  /**
+   * Get Info.
+   */
   public static function getInfo() {
   public static function getInfo() {
     return array(
     return array(
       'name' => 'XML sitemap node',
       'name' => 'XML sitemap node',
@@ -17,21 +37,44 @@ class XMLSitemapNodeFunctionalTest extends XMLSitemapTestHelper {
     );
     );
   }
   }
 
 
-  function setUp($modules = array()) {
+  /**
+   * Setup.
+   */
+  public function setUp($modules = array()) {
     $modules[] = 'xmlsitemap_node';
     $modules[] = 'xmlsitemap_node';
     $modules[] = 'comment';
     $modules[] = 'comment';
     parent::setUp($modules);
     parent::setUp($modules);
 
 
-    $this->admin_user = $this->drupalCreateUser(array('administer nodes', 'bypass node access', 'administer content types', 'administer xmlsitemap'));
-    $this->normal_user = $this->drupalCreateUser(array('create page content', 'edit any page content', 'access content', 'view own unpublished content'));
+    $this->admin_user = $this->drupalCreateUser(array(
+      'administer nodes',
+      'bypass node access',
+      'administer content types',
+      'administer xmlsitemap',
+    ));
+    $this->normal_user = $this->drupalCreateUser(array(
+      'create page content',
+      'edit any page content',
+      'access content',
+      'view own unpublished content',
+    ));
     xmlsitemap_link_bundle_settings_save('node', 'page', array('status' => 1, 'priority' => 0.5));
     xmlsitemap_link_bundle_settings_save('node', 'page', array('status' => 1, 'priority' => 0.5));
   }
   }
 
 
-  function testNodeSettings() {
+  /**
+   * Node Settings.
+   */
+  public function testNodeSettings() {
     $body_field = 'body[' . LANGUAGE_NONE . '][0][value]';
     $body_field = 'body[' . LANGUAGE_NONE . '][0][value]';
 
 
     $node = $this->drupalCreateNode(array('status' => FALSE, 'uid' => $this->normal_user->uid));
     $node = $this->drupalCreateNode(array('status' => FALSE, 'uid' => $this->normal_user->uid));
-    $this->assertSitemapLinkValues('node', $node->nid, array('access' => 0, 'status' => 1, 'priority' => 0.5, 'status_override' => 0, 'priority_override' => 0));
+    $this->cronRun();
+    $this->assertSitemapLinkValues('node', $node->nid, array(
+      'access' => 0,
+      'status' => 1,
+      'priority' => 0.5,
+      'status_override' => 0,
+      'priority_override' => 0,
+    ));
 
 
     $this->drupalLogin($this->normal_user);
     $this->drupalLogin($this->normal_user);
     $this->drupalGet('node/' . $node->nid . '/edit');
     $this->drupalGet('node/' . $node->nid . '/edit');
@@ -44,7 +87,14 @@ class XMLSitemapNodeFunctionalTest extends XMLSitemapTestHelper {
     );
     );
     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
     $this->assertText('Basic page Test node title has been updated.');
     $this->assertText('Basic page Test node title has been updated.');
-    $this->assertSitemapLinkValues('node', $node->nid, array('access' => 0, 'status' => 1, 'priority' => 0.5, 'status_override' => 0, 'priority_override' => 0));
+    $this->cronRun();
+    $this->assertSitemapLinkValues('node', $node->nid, array(
+      'access' => 0,
+      'status' => 1,
+      'priority' => 0.5,
+      'status_override' => 0,
+      'priority_override' => 0,
+    ));
 
 
     $this->drupalLogin($this->admin_user);
     $this->drupalLogin($this->admin_user);
     $this->drupalGet('node/' . $node->nid . '/edit');
     $this->drupalGet('node/' . $node->nid . '/edit');
@@ -58,7 +108,14 @@ class XMLSitemapNodeFunctionalTest extends XMLSitemapTestHelper {
     );
     );
     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
     $this->assertText('Basic page Test node title has been updated.');
     $this->assertText('Basic page Test node title has been updated.');
-    $this->assertSitemapLinkValues('node', $node->nid, array('access' => 1, 'status' => 0, 'priority' => 0.9, 'status_override' => 1, 'priority_override' => 1));
+    $this->cronRun();
+    $this->assertSitemapLinkValues('node', $node->nid, array(
+      'access' => 1,
+      'status' => 0,
+      'priority' => 0.9,
+      'status_override' => 1,
+      'priority_override' => 1,
+    ));
 
 
     $edit = array(
     $edit = array(
       'xmlsitemap[status]' => 'default',
       'xmlsitemap[status]' => 'default',
@@ -67,16 +124,24 @@ class XMLSitemapNodeFunctionalTest extends XMLSitemapTestHelper {
     );
     );
     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
     $this->assertText('Basic page Test node title has been updated.');
     $this->assertText('Basic page Test node title has been updated.');
-    $this->assertSitemapLinkValues('node', $node->nid, array('access' => 0, 'status' => 1, 'priority' => 0.5, 'status_override' => 0, 'priority_override' => 0));
+    $this->cronRun();
+    $this->assertSitemapLinkValues('node', $node->nid, array(
+      'access' => 0,
+      'status' => 1,
+      'priority' => 0.5,
+      'status_override' => 0,
+      'priority_override' => 0,
+    ));
   }
   }
 
 
   /**
   /**
    * Test the content type settings.
    * Test the content type settings.
    */
    */
-  function testTypeSettings() {
+  public function testTypeSettings() {
     $this->drupalLogin($this->admin_user);
     $this->drupalLogin($this->admin_user);
 
 
     $node_old = $this->drupalCreateNode();
     $node_old = $this->drupalCreateNode();
+    $this->cronRun();
     $this->assertSitemapLinkValues('node', $node_old->nid, array('status' => 1, 'priority' => 0.5));
     $this->assertSitemapLinkValues('node', $node_old->nid, array('status' => 1, 'priority' => 0.5));
 
 
     $edit = array(
     $edit = array(
@@ -87,6 +152,7 @@ class XMLSitemapNodeFunctionalTest extends XMLSitemapTestHelper {
     $this->assertText('The content type Basic page has been updated.');
     $this->assertText('The content type Basic page has been updated.');
 
 
     $node = $this->drupalCreateNode();
     $node = $this->drupalCreateNode();
+    $this->cronRun();
     $this->assertSitemapLinkValues('node', $node->nid, array('status' => 0, 'priority' => 0.0));
     $this->assertSitemapLinkValues('node', $node->nid, array('status' => 0, 'priority' => 0.0));
     $this->assertSitemapLinkValues('node', $node_old->nid, array('status' => 0, 'priority' => 0.0));
     $this->assertSitemapLinkValues('node', $node_old->nid, array('status' => 0, 'priority' => 0.0));
 
 
@@ -98,9 +164,18 @@ class XMLSitemapNodeFunctionalTest extends XMLSitemapTestHelper {
     $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
     $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
     $this->assertText('Changed the content type of 2 posts from page to page2.');
     $this->assertText('Changed the content type of 2 posts from page to page2.');
     $this->assertText('The content type Basic page has been updated.');
     $this->assertText('The content type Basic page has been updated.');
-
-    $this->assertSitemapLinkValues('node', $node->nid, array('subtype' => 'page2', 'status' => 1, 'priority' => 0.5));
-    $this->assertSitemapLinkValues('node', $node_old->nid, array('subtype' => 'page2', 'status' => 1, 'priority' => 0.5));
+    $this->cronRun();
+
+    $this->assertSitemapLinkValues('node', $node->nid, array(
+      'subtype' => 'page2',
+      'status' => 1,
+      'priority' => 0.5,
+    ));
+    $this->assertSitemapLinkValues('node', $node_old->nid, array(
+      'subtype' => 'page2',
+      'status' => 1,
+      'priority' => 0.5,
+    ));
     $this->assertEqual(count(xmlsitemap_link_load_multiple(array('type' => 'node', 'subtype' => 'page'))), 0);
     $this->assertEqual(count(xmlsitemap_link_load_multiple(array('type' => 'node', 'subtype' => 'page'))), 0);
     $this->assertEqual(count(xmlsitemap_link_load_multiple(array('type' => 'node', 'subtype' => 'page2'))), 2);
     $this->assertEqual(count(xmlsitemap_link_load_multiple(array('type' => 'node', 'subtype' => 'page2'))), 2);
 
 
@@ -112,7 +187,7 @@ class XMLSitemapNodeFunctionalTest extends XMLSitemapTestHelper {
   /**
   /**
    * Test the import of old nodes via cron.
    * Test the import of old nodes via cron.
    */
    */
-  function testCron() {
+  public function testCron() {
     $limit = 5;
     $limit = 5;
     variable_set('xmlsitemap_batch_limit', $limit);
     variable_set('xmlsitemap_batch_limit', $limit);
 
 
@@ -127,17 +202,21 @@ class XMLSitemapNodeFunctionalTest extends XMLSitemapTestHelper {
 
 
     // Clear all the node link data so we can emulate 'old' nodes.
     // Clear all the node link data so we can emulate 'old' nodes.
     db_delete('xmlsitemap')
     db_delete('xmlsitemap')
-      ->condition('type', 'node')
-      ->execute();
+        ->condition('type', 'node')
+        ->execute();
 
 
     // Run cron to import old nodes.
     // Run cron to import old nodes.
     xmlsitemap_node_cron();
     xmlsitemap_node_cron();
 
 
     for ($i = 1; $i <= ($limit + 1); $i++) {
     for ($i = 1; $i <= ($limit + 1); $i++) {
-      $node = array_pop($nodes);
+      $node = array_shift($nodes);
       if ($i <= $limit) {
       if ($i <= $limit) {
         // The first $limit nodes should be inserted.
         // The first $limit nodes should be inserted.
-        $this->assertSitemapLinkValues('node', $node->nid, array('access' => 1, 'status' => 1, 'lastmod' => $node->changed));
+        $this->assertSitemapLinkValues('node', $node->nid, array(
+          'access' => 1,
+          'status' => 1,
+          'lastmod' => $node->changed,
+        ));
       }
       }
       else {
       else {
         // Any beyond $limit should not be in the sitemap.
         // Any beyond $limit should not be in the sitemap.
@@ -145,4 +224,5 @@ class XMLSitemapNodeFunctionalTest extends XMLSitemapTestHelper {
       }
       }
     }
     }
   }
   }
+
 }
 }

+ 83 - 0
sites/all/modules/xmlsitemap/xmlsitemap_taxonomy/README.txt

@@ -0,0 +1,83 @@
+CONTENTS OF THIS FILE
+---------------------
+
+* Introduction
+* Requirements
+* Recommended modules
+* Installation
+* Configuration
+* Maintainers
+
+
+INTRODUCTION
+------------
+
+The XML sitemap taxonomy module, part of the XML sitemap
+(https://www.drupal.org/project/xmlsitemap) package, adds taxonomy term links
+to the sitemap. The XML sitemap module creates a sitemap that conforms to the
+sitemaps.org specification. This helps search engines to more intelligently
+crawl a website and keep their results up to date.
+
+* For a full description of the module visit
+https://www.drupal.org/documentation/modules/xmlsitemap
+
+* To submit bug reports and feature suggestions, or to track changes visit
+https://www.drupal.org/project/issues/xmlsitemap
+
+
+REQUIREMENTS
+------------
+
+This module requires the following modules:
+
+XML sitemap - (https://www.drupal.org/project/xmlsitemap)
+
+
+RECOMMENDED MODULES
+-------------------
+
+* Ctools - (https://www.drupal.org/project/ctools)
+* RobotsTxt - (https://www.drupal.org/project/robotstxt)
+* Site Verification - (https://www.drupal.org/project/site_verify)
+* Browscap - (https://www.drupal.org/project/browscap)
+* Vertical Tabs - (https://www.drupal.org/project/vertical_tabs)
+
+
+INSTALLATION
+------------
+
+This is a submodule of the XML sitemap module. Install the XML sitemap module as
+you would normally install a contributed Drupal module. Visit
+https://www.drupal.org/node/895232 for more information.
+
+
+CONFIGURATION
+-------------
+
+1. Install the XML sitemap module.
+2. Enable the XML sitemap module.
+3. To include taxonomy terms in the sitemap, enable the XML sitemap taxonomy
+   submodule.
+4. Navigate to Administration > Structure > Taxonomy.
+5. To include a whole vocabulary in the sitemap, click "edit vocabulary".
+   Select the XML sitemap field set. Under "Inclusion" change "Excluded" to
+   become "Included". Save.
+6. To include a single vocabulary term in the sitemap, select edit vocabulary.
+   Select the vocabulary term to be included. Select the XML sitemap field set.
+   Under "Inclusion" change "Excluded" to become "Included". Save.
+7. Once that is all complete, go to Configurations > Search and Metadata > XML
+   Sitemap.
+8. Select the Rebuild Links tab in the upper right.
+9. Select "Rebuild sitemap" even if the message says that you do not need to.
+10. Now you're taken back to the configuration page which shows you the link to
+   your XML sitemap which you can click and confirm that pages have been added.
+
+
+MAINTAINERS
+-----------
+
+* Andrei Mateescu (amateescu) - https://www.drupal.org/u/amateescu
+* Renato Gonçalves (RenatoG) - https://www.drupal.org/u/RenatoG
+* Dave Reid - https://www.drupal.org/u/dave-reid
+* Juampy NR (juampynr) - https://www.drupal.org/u/juampynr
+* Tasya Rukmana (tadityar) - https://www.drupal.org/u/tadityar

+ 3 - 6
sites/all/modules/xmlsitemap/xmlsitemap_taxonomy/xmlsitemap_taxonomy.info

@@ -4,13 +4,10 @@ package = XML sitemap
 core = 7.x
 core = 7.x
 dependencies[] = xmlsitemap
 dependencies[] = xmlsitemap
 dependencies[] = taxonomy
 dependencies[] = taxonomy
-files[] = xmlsitemap_taxonomy.module
-files[] = xmlsitemap_taxonomy.install
 files[] = xmlsitemap_taxonomy.test
 files[] = xmlsitemap_taxonomy.test
 
 
-; Information added by Drupal.org packaging script on 2016-05-25
-version = "7.x-2.3"
+; Information added by Drupal.org packaging script on 2018-10-09
+version = "7.x-2.6"
 core = "7.x"
 core = "7.x"
 project = "xmlsitemap"
 project = "xmlsitemap"
-datestamp = "1464191061"
-
+datestamp = "1539120486"

+ 1 - 1
sites/all/modules/xmlsitemap/xmlsitemap_taxonomy/xmlsitemap_taxonomy.install

@@ -2,7 +2,7 @@
 
 
 /**
 /**
  * @file
  * @file
- * Install and uninstall schema and functions for the xmlsitemap_taxonomy module.
+ * Install and uninstall schema and functions for the xmlsitemap_taxonomy.
  */
  */
 
 
 /**
 /**

+ 36 - 18
sites/all/modules/xmlsitemap/xmlsitemap_taxonomy/xmlsitemap_taxonomy.module

@@ -1,5 +1,10 @@
 <?php
 <?php
 
 
+/**
+ * @file
+ * Main file for XML sitemap taxonomy.
+ */
+
 /**
 /**
  * Implements hook_entity_info_alter().
  * Implements hook_entity_info_alter().
  */
  */
@@ -43,7 +48,7 @@ function xmlsitemap_taxonomy_xmlsitemap_index_links($limit) {
 /**
 /**
  * Process taxonomy term sitemap links.
  * Process taxonomy term sitemap links.
  *
  *
- * @param $tids
+ * @param array $tids
  *   An array of taxonomy term IDs.
  *   An array of taxonomy term IDs.
  */
  */
 function xmlsitemap_taxonomy_xmlsitemap_process_taxonomy_term_links(array $tids) {
 function xmlsitemap_taxonomy_xmlsitemap_process_taxonomy_term_links(array $tids) {
@@ -103,7 +108,7 @@ function xmlsitemap_taxonomy_vocabulary_update(stdClass $vocabulary) {
 }
 }
 
 
 /**
 /**
- * Implements hook_taxonomy_term_insert() {
+ * Implements hook_taxonomy_term_insert().
  */
  */
 function xmlsitemap_taxonomy_term_insert(stdClass $term) {
 function xmlsitemap_taxonomy_term_insert(stdClass $term) {
   $link = xmlsitemap_taxonomy_create_link($term);
   $link = xmlsitemap_taxonomy_create_link($term);
@@ -111,7 +116,7 @@ function xmlsitemap_taxonomy_term_insert(stdClass $term) {
 }
 }
 
 
 /**
 /**
- * Implements hook_taxonomy_term_update() {
+ * Implements hook_taxonomy_term_update().
  */
  */
 function xmlsitemap_taxonomy_term_update(stdClass $term) {
 function xmlsitemap_taxonomy_term_update(stdClass $term) {
   $link = xmlsitemap_taxonomy_create_link($term);
   $link = xmlsitemap_taxonomy_create_link($term);
@@ -119,7 +124,7 @@ function xmlsitemap_taxonomy_term_update(stdClass $term) {
 }
 }
 
 
 /**
 /**
- * Implements hook_taxonomy_term_delete() {
+ * Implements hook_taxonomy_term_delete().
  */
  */
 function xmlsitemap_taxonomy_term_delete(stdClass $term) {
 function xmlsitemap_taxonomy_term_delete(stdClass $term) {
   xmlsitemap_link_delete('taxonomy_term', $term->tid);
   xmlsitemap_link_delete('taxonomy_term', $term->tid);
@@ -143,9 +148,10 @@ function xmlsitemap_taxonomy_field_extra_fields() {
 /**
 /**
  * Create a sitemap link from a taxonomy term.
  * Create a sitemap link from a taxonomy term.
  *
  *
- * @param $term
+ * @param object $term
  *   A taxonomy term object.
  *   A taxonomy term object.
- * @return
+ *
+ * @return array
  *   An array representing a sitemap link.
  *   An array representing a sitemap link.
  */
  */
 function xmlsitemap_taxonomy_create_link(stdClass &$term) {
 function xmlsitemap_taxonomy_create_link(stdClass &$term) {
@@ -182,20 +188,22 @@ function xmlsitemap_taxonomy_create_link(stdClass &$term) {
 
 
 /**
 /**
  * Calculate the priority of a taxonomy term based on depth and weight.
  * Calculate the priority of a taxonomy term based on depth and weight.
+ *
+ * Function xmlsitemap_taxonomy_calculate_term_priority(stdClass $term) {
+ *  // Calculate priority.
+ *  // Min weight = -128
+ *  // Max weight = 127
+ *  // Max depth = ?
+ * }
  */
  */
-//function xmlsitemap_taxonomy_calculate_term_priority(stdClass $term) {
-//  // Calculate priority.
-//  // Min weight = -128
-//  // Max weight = 127
-//  // Max depth = ?
-//}
 
 
 /**
 /**
  * Find the tree depth of a taxonomy term.
  * Find the tree depth of a taxonomy term.
  *
  *
- * @param $term
+ * @param object $term
  *   A taxonomy term object.
  *   A taxonomy term object.
- * @return
+ *
+ * @return array
  *   The tree depth of the term.
  *   The tree depth of the term.
  */
  */
 function xmlsitemap_taxonomy_get_term_depth(stdClass $term) {
 function xmlsitemap_taxonomy_get_term_depth(stdClass $term) {
@@ -221,12 +229,16 @@ function xmlsitemap_taxonomy_get_term_depth(stdClass $term) {
 /**
 /**
  * Find the number of nodes that are associated with a taxonomy term.
  * Find the number of nodes that are associated with a taxonomy term.
  *
  *
- * @param $term
+ * @param obejct $term
  *   A taxonomy term object.
  *   A taxonomy term object.
- * @return
+ *
+ * @return int
  *   The number of nodes associated with the term.
  *   The number of nodes associated with the term.
+ *
+ * @codingStandardsIgnoreStart
  */
  */
 function xmlsitemap_taxonomy_get_node_count(stdClass $term) {
 function xmlsitemap_taxonomy_get_node_count(stdClass $term) {
+  // @codingStandardsIgnoreEnd
   // @todo Use db_rewrite_sql() w/ switch user.
   // @todo Use db_rewrite_sql() w/ switch user.
   return db_query_range("SELECT COUNT(ti.nid) FROM {taxonomy_index} ti LEFT JOIN {node n} USING (nid) WHERE ti.tid = :tid AND n.status = 1", 0, 1, array(':tid' => $term->tid))->fetchField();
   return db_query_range("SELECT COUNT(ti.nid) FROM {taxonomy_index} ti LEFT JOIN {node n} USING (nid) WHERE ti.tid = :tid AND n.status = 1", 0, 1, array(':tid' => $term->tid))->fetchField();
 }
 }
@@ -234,7 +246,7 @@ function xmlsitemap_taxonomy_get_node_count(stdClass $term) {
 /**
 /**
  * Implements hook_entity_query_alter().
  * Implements hook_entity_query_alter().
  *
  *
- * @todo Remove when http://drupal.org/node/1054162 is fixed.
+ * @todo Remove when https://www.drupal.org/node/1054162 is fixed.
  */
  */
 function xmlsitemap_taxonomy_entity_query_alter($query) {
 function xmlsitemap_taxonomy_entity_query_alter($query) {
   $conditions = &$query->entityConditions;
   $conditions = &$query->entityConditions;
@@ -243,7 +255,13 @@ function xmlsitemap_taxonomy_entity_query_alter($query) {
   if (isset($conditions['entity_type']) && $conditions['entity_type']['value'] == 'taxonomy_term' && isset($conditions['bundle'])) {
   if (isset($conditions['entity_type']) && $conditions['entity_type']['value'] == 'taxonomy_term' && isset($conditions['bundle'])) {
 
 
     // We can only support the operators that are explicit in values.
     // We can only support the operators that are explicit in values.
-    if (in_array($conditions['bundle']['operator'], array(NULL, '=', '!=', 'IN', 'NOT IN'))) {
+    if (in_array($conditions['bundle']['operator'], array(
+      NULL,
+      '=',
+      '!=',
+      'IN',
+      'NOT IN',
+    ))) {
       $vids = array();
       $vids = array();
 
 
       // Convert vocabulary machine names to vocabulary IDs.
       // Convert vocabulary machine names to vocabulary IDs.

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