updated admin_menu, entity_translation, addressfield, addressfield_token, autocomplete_deluxe
This commit is contained in:
		@@ -1,65 +1,84 @@
 | 
			
		||||
CONTENTS OF THIS FILE
 | 
			
		||||
---------------------
 | 
			
		||||
 | 
			
		||||
-- SUMMARY --
 | 
			
		||||
 * Introduction
 | 
			
		||||
 * Requirements
 | 
			
		||||
 * Installation
 | 
			
		||||
 * Configuration
 | 
			
		||||
 * Customization
 | 
			
		||||
 * Troubleshooting
 | 
			
		||||
 * FAQ
 | 
			
		||||
 * Maintainers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
INTRODUCTION
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
The Administration menu module displays the entire administrative menu tree (and
 | 
			
		||||
most local tasks) in a drop-down menu, providing administrators one- or
 | 
			
		||||
two-click access to most pages.  Other modules may also add menu links to the
 | 
			
		||||
menu using hook_admin_menu_output_alter().
 | 
			
		||||
 | 
			
		||||
For a full description of the module, visit the project page:
 | 
			
		||||
  http://drupal.org/project/admin_menu
 | 
			
		||||
For a full description of the project visit the project page:
 | 
			
		||||
http://drupal.org/project/admin_menu
 | 
			
		||||
 | 
			
		||||
To submit bug reports and feature suggestions, or to track changes:
 | 
			
		||||
  http://drupal.org/project/issues/admin_menu
 | 
			
		||||
http://drupal.org/project/issues/admin_menu
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- REQUIREMENTS --
 | 
			
		||||
REQUIREMENTS
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
None.
 | 
			
		||||
No special requirements
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- INSTALLATION --
 | 
			
		||||
INSTALLATION
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
* Install as usual, see http://drupal.org/node/895232 for further information.
 | 
			
		||||
Install as you would normally install a contributed Drupal. See:
 | 
			
		||||
https://drupal.org/documentation/install/modules-themes/modules-7 for further
 | 
			
		||||
information.
 | 
			
		||||
 | 
			
		||||
* You likely want to disable Toolbar module, since its output clashes with
 | 
			
		||||
  Administration menu.
 | 
			
		||||
 * You likely want to disable Toolbar module, since its output clashes with
 | 
			
		||||
 Administration menu.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- CONFIGURATION --
 | 
			
		||||
CONFIGURATION
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
* Configure user permissions in Administration » People » Permissions:
 | 
			
		||||
 * Configure user permissions in Administration » People » Permissions:
 | 
			
		||||
 | 
			
		||||
  - Use the administration pages and help (System module)
 | 
			
		||||
   - Use the administration pages and help (System module)
 | 
			
		||||
 | 
			
		||||
    The top-level administration categories require this permission to be
 | 
			
		||||
    accessible. The administration menu will be empty unless this permission is
 | 
			
		||||
    granted.
 | 
			
		||||
     The top-level administration categories require this permission to be
 | 
			
		||||
     accessible. The administration menu will be empty unless this permission is
 | 
			
		||||
     granted.
 | 
			
		||||
 | 
			
		||||
  - Access administration menu
 | 
			
		||||
   - Access administration menu
 | 
			
		||||
 | 
			
		||||
    Users in roles with the "Access administration menu" permission will see
 | 
			
		||||
    the administration menu at the top of each page.
 | 
			
		||||
     Users in roles with the "Access administration menu" permission will see
 | 
			
		||||
     the administration menu at the top of each page.
 | 
			
		||||
 | 
			
		||||
  - Display Drupal links
 | 
			
		||||
   - Display Drupal links
 | 
			
		||||
 | 
			
		||||
    Users in roles with the "Display drupal links" permission will receive
 | 
			
		||||
    links to drupal.org issue queues for all enabled contributed modules. The
 | 
			
		||||
    issue queue links appear under the administration menu icon.
 | 
			
		||||
     Users in roles with the "Display drupal links" permission will receive
 | 
			
		||||
     links to drupal.org issue queues for all enabled contributed modules. The
 | 
			
		||||
     issue queue links appear under the administration menu icon.
 | 
			
		||||
 | 
			
		||||
  Note that the menu items displayed in the administration menu depend on the
 | 
			
		||||
  actual permissions of the viewing user. For example, the "People" menu item
 | 
			
		||||
  is not displayed to a user who is not a member of a role with the "Administer
 | 
			
		||||
  users" permission.
 | 
			
		||||
     Note that the menu items displayed in the administration menu depend on the
 | 
			
		||||
     actual permissions of the viewing user. For example, the "People" menu item
 | 
			
		||||
     is not displayed to a user who is not a member of a role with the
 | 
			
		||||
     "Administer users" permission.
 | 
			
		||||
 | 
			
		||||
* Customize the menu settings in Administration » Configuration and modules »
 | 
			
		||||
  Administration » Administration menu.
 | 
			
		||||
 * Customize the menu settings in Administration » Configuration and modules »
 | 
			
		||||
   Administration » Administration menu.
 | 
			
		||||
 | 
			
		||||
* To prevent administrative menu items from appearing twice, you may hide the
 | 
			
		||||
  "Management" menu block.
 | 
			
		||||
 * To prevent administrative menu items from appearing twice, you may hide the
 | 
			
		||||
   "Management" menu block.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- CUSTOMIZATION --
 | 
			
		||||
CUSTOMIZATION
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
* To override the default administration menu icon, you may:
 | 
			
		||||
 | 
			
		||||
@@ -82,12 +101,13 @@ None.
 | 
			
		||||
  body #admin-menu { font-size: 10px; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- TROUBLESHOOTING --
 | 
			
		||||
TROUBLESHOOTING
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
* If the menu does not display, check the following:
 | 
			
		||||
 | 
			
		||||
  - Are the "Access administration menu" and "Use the administration pages and help"
 | 
			
		||||
    permissions enabled for the appropriate roles?
 | 
			
		||||
  - Are the "Access administration menu" and "Use the administration pages and
 | 
			
		||||
    help" permissions enabled for the appropriate roles?
 | 
			
		||||
 | 
			
		||||
  - Does html.tpl.php of your theme output the $page_bottom variable?
 | 
			
		||||
 | 
			
		||||
@@ -99,90 +119,102 @@ None.
 | 
			
		||||
  See http://drupal.org/node/195386 for further information.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- FAQ --
 | 
			
		||||
FAQ
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
Q: When the administration menu module is enabled, blank space is added to the
 | 
			
		||||
   bottom of my theme. Why?
 | 
			
		||||
 Q: When the administration menu module is enabled, blank space is added to the
 | 
			
		||||
    bottom of my theme. Why?
 | 
			
		||||
 | 
			
		||||
A: This is caused by a long list of links to module issue queues at Drupal.org.
 | 
			
		||||
   Use Administer >> User management >> Permissions to disable the "display
 | 
			
		||||
   drupal links" permission for all appropriate roles. Note that since UID 1
 | 
			
		||||
   automatically receives all permissions, the list of issue queue links cannot
 | 
			
		||||
   be disabled for UID 1.
 | 
			
		||||
 A: This is caused by a long list of links to module issue queues at Drupal.org.
 | 
			
		||||
    Use Administer >> User management >> Permissions to disable the "display
 | 
			
		||||
    drupal links" permission for all appropriate roles. Note that since UID 1
 | 
			
		||||
    automatically receives all permissions, the list of issue queue links cannot
 | 
			
		||||
    be disabled for UID 1.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Q: After upgrading to 6.x-1.x, the menu disappeared. Why?
 | 
			
		||||
 Q: After upgrading to 6.x-1.x, the menu disappeared. Why?
 | 
			
		||||
 | 
			
		||||
A: You may need to regenerate your menu. Visit
 | 
			
		||||
   http://example.com/admin/build/modules to regenerate your menu (substitute
 | 
			
		||||
   your site name for example.com).
 | 
			
		||||
 A: You may need to regenerate your menu. Visit
 | 
			
		||||
    http://example.com/admin/build/modules to regenerate your menu (substitute
 | 
			
		||||
    your site name for example.com).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Q: Can I configure the administration menu module to display another menu (like
 | 
			
		||||
   the Navigation menu, for instance)?
 | 
			
		||||
 Q: Can I configure the administration menu module to display another menu (like
 | 
			
		||||
    the Navigation menu, for instance)?
 | 
			
		||||
 | 
			
		||||
A: No. As the name implies, administration menu module is for administrative
 | 
			
		||||
   menu links only. However, you can copy and paste the contents of
 | 
			
		||||
   admin_menu.css into your theme's stylesheet and replace #admin-menu with any
 | 
			
		||||
   other menu block id (#block-menu-1, for example).
 | 
			
		||||
 A: No. As the name implies, administration menu module is for administrative
 | 
			
		||||
    menu links only. However, you can copy and paste the contents of
 | 
			
		||||
    admin_menu.css into your theme's stylesheet and replace #admin-menu with any
 | 
			
		||||
    other menu block id (#block-menu-1, for example).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Q: Sometimes, the user counter displays a lot of anonymous users, but no spike
 | 
			
		||||
   of users or requests appear in Google Analytics or other tracking tools.
 | 
			
		||||
 Q: Sometimes, the user counter displays a lot of anonymous users, but no spike
 | 
			
		||||
    of users or requests appear in Google Analytics or other tracking tools.
 | 
			
		||||
 | 
			
		||||
A: If your site was concurrently spidered by search-engine robots, it may have
 | 
			
		||||
   a significant number of anonymous users for a short time. Most web tracking
 | 
			
		||||
   tools like Google Analytics automatically filter out these requests.
 | 
			
		||||
 A: If your site was concurrently spidered by search-engine robots, it may have
 | 
			
		||||
    a significant number of anonymous users for a short time. Most web tracking
 | 
			
		||||
    tools like Google Analytics automatically filter out these requests.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Q: I enabled "Aggregate and compress CSS files", but admin_menu.css is still
 | 
			
		||||
   there. Is this normal?
 | 
			
		||||
 Q: I enabled "Aggregate and compress CSS files", but admin_menu.css is still
 | 
			
		||||
    there. Is this normal?
 | 
			
		||||
 | 
			
		||||
A: Yes, this is the intended behavior. the administration menu module only loads
 | 
			
		||||
   its stylesheet as needed (i.e., on page requests by logged-on, administrative
 | 
			
		||||
   users).
 | 
			
		||||
 A: Yes, this is the intended behavior. the administration menu module only
 | 
			
		||||
    loads its stylesheet as needed (i.e., on page requests by logged-on,
 | 
			
		||||
    administrative users).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Q: Why are sub-menus not visible in Opera?
 | 
			
		||||
 Q: Why are sub-menus not visible in Opera?
 | 
			
		||||
 | 
			
		||||
A: In the Opera browser preferences under "web pages" there is an option to fit
 | 
			
		||||
   to width. By disabling this option, sub-menus in the administration menu
 | 
			
		||||
   should appear.
 | 
			
		||||
 A: In the Opera browser preferences under "web pages" there is an option to fit
 | 
			
		||||
    to width. By disabling this option, sub-menus in the administration menu
 | 
			
		||||
    should appear.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Q: How can the administration menu be hidden on certain pages?
 | 
			
		||||
 Q: How can the administration menu be hidden on certain pages?
 | 
			
		||||
 | 
			
		||||
A: You can suppress it by simply calling the following function in PHP:
 | 
			
		||||
 A: You can suppress it by simply calling the following function in PHP:
 | 
			
		||||
    module_invoke('admin_menu', 'suppress');
 | 
			
		||||
 | 
			
		||||
     module_invoke('admin_menu', 'suppress');
 | 
			
		||||
 | 
			
		||||
   However, this needs to happen as early as possible in the page request, so
 | 
			
		||||
   placing it in the theming layer (resp. a page template file) is too late.
 | 
			
		||||
   Ideally, the function is called in hook_init() in a custom module.  If you do
 | 
			
		||||
   not have a custom module, placing it into some conditional code at the top of
 | 
			
		||||
   template.php may work out, too.
 | 
			
		||||
    However, this needs to happen as early as possible in the page request, so
 | 
			
		||||
    placing it in the theming layer (resp. a page template file) is too late.
 | 
			
		||||
    Ideally, the function is called in hook_init() in a custom module.  If you
 | 
			
		||||
    do not have a custom module, placing it into some conditional code at the
 | 
			
		||||
    top of template.php may work out, too.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- CONTACT --
 | 
			
		||||
Q: What does the "Administration Development Tools" module do?
 | 
			
		||||
 | 
			
		||||
A: The Administration Development Tools adds a jQuery Debugger which allows
 | 
			
		||||
   a developer to debug and inspect arbitrary data/variables in Firebug's
 | 
			
		||||
   console, and also to access them again in the global window object
 | 
			
		||||
   (optionally using a named identifier, e.g. window.debug.myValue).
 | 
			
		||||
   Chainable via jQuery. Especially useful for re-accessing and debugging
 | 
			
		||||
   selected data via Firebug's console.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
MAINTAINERS
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
Current maintainers:
 | 
			
		||||
* Daniel F. Kudwien (sun) - http://drupal.org/user/54136
 | 
			
		||||
* Peter Wolanin (pwolanin) - http://drupal.org/user/49851
 | 
			
		||||
* Stefan M. Kudwien (smk-ka) - http://drupal.org/user/48898
 | 
			
		||||
* Dave Reid (Dave Reid) - http://drupal.org/user/53892
 | 
			
		||||
 * Daniel F. Kudwien (sun) - http://drupal.org/user/54136
 | 
			
		||||
 * Peter Wolanin (pwolanin) - http://drupal.org/user/49851
 | 
			
		||||
 * Stefan M. Kudwien (smk-ka) - http://drupal.org/user/48898
 | 
			
		||||
 * Dave Reid (Dave Reid) - http://drupal.org/user/53892
 | 
			
		||||
 * Truls S. Yggeseth (truls1502) - http://drupal.org/user/325866
 | 
			
		||||
 * Sebastian Siemssen (fubhy) - https://www.drupal.org/user/761344
 | 
			
		||||
 | 
			
		||||
Major rewrite for Drupal 6 by Peter Wolanin (pwolanin).
 | 
			
		||||
 | 
			
		||||
This project has been sponsored by:
 | 
			
		||||
* UNLEASHED MIND
 | 
			
		||||
  Specialized in consulting and planning of Drupal powered sites, UNLEASHED
 | 
			
		||||
  MIND offers installation, development, theming, customization, and hosting
 | 
			
		||||
  to get you started. Visit http://www.unleashedmind.com for more information.
 | 
			
		||||
 * UNLEASHED MIND
 | 
			
		||||
   Specialized in consulting and planning of Drupal powered sites, UNLEASHED
 | 
			
		||||
   MIND offers installation, development, theming, customization, and hosting
 | 
			
		||||
   to get you started. Visit http://www.unleashedmind.com for more information.
 | 
			
		||||
 | 
			
		||||
* Lullabot
 | 
			
		||||
  Friendly Drupal experts providing professional consulting & education
 | 
			
		||||
  services. Visit http://www.lullabot.com for more information.
 | 
			
		||||
 | 
			
		||||
* Acquia
 | 
			
		||||
  Commercially Supported Drupal. Visit http://acquia.com for more information.
 | 
			
		||||
 * Lullabot
 | 
			
		||||
   Friendly Drupal experts providing professional consulting & education
 | 
			
		||||
   services. Visit http://www.lullabot.com for more information.
 | 
			
		||||
 | 
			
		||||
 * Acquia
 | 
			
		||||
   Commercially Supported Drupal. Visit http://acquia.com for more information.
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,8 @@ package = Administration
 | 
			
		||||
core = 7.x
 | 
			
		||||
scripts[] = admin_devel.js
 | 
			
		||||
 | 
			
		||||
; Information added by Drupal.org packaging script on 2014-12-19
 | 
			
		||||
version = "7.x-3.0-rc5"
 | 
			
		||||
; Information added by Drupal.org packaging script on 2018-12-03
 | 
			
		||||
version = "7.x-3.0-rc6"
 | 
			
		||||
core = "7.x"
 | 
			
		||||
project = "admin_menu"
 | 
			
		||||
datestamp = "1419029284"
 | 
			
		||||
 | 
			
		||||
datestamp = "1543859284"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
 | 
			
		||||
#admin-menu {
 | 
			
		||||
  text-align: right;
 | 
			
		||||
}
 | 
			
		||||
@@ -25,7 +24,7 @@
 | 
			
		||||
  border-right: 0;
 | 
			
		||||
}
 | 
			
		||||
#admin-menu .dropdown .admin-menu-tab a {
 | 
			
		||||
  border-left: 1px solid #52565E;
 | 
			
		||||
  border-left: 1px solid #52565e;
 | 
			
		||||
  border-right: 0;
 | 
			
		||||
}
 | 
			
		||||
#admin-menu .dropdown li li a {
 | 
			
		||||
@@ -42,13 +41,13 @@
 | 
			
		||||
/* Second-level lists */
 | 
			
		||||
#admin-menu .dropdown li ul {
 | 
			
		||||
  left: auto;
 | 
			
		||||
  right: -999em;
 | 
			
		||||
  right: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Third-and-above-level lists */
 | 
			
		||||
#admin-menu .dropdown li li.expandable ul {
 | 
			
		||||
  margin-left: 0;
 | 
			
		||||
  margin-right: 160px;
 | 
			
		||||
  margin-left: 0 !important;
 | 
			
		||||
  margin-right: 160px !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Lists nested under hovered list items */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,8 @@
 | 
			
		||||
(function($) {
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
(function ($) {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Live preview of Administration menu components.
 | 
			
		||||
@@ -45,9 +49,9 @@ Drupal.behaviors.adminMenuPermissionsSetupHelp = {
 | 
			
		||||
              // Figure out which is the other, check whether it still disabled,
 | 
			
		||||
              // and if so, ask whether to auto-enable it.
 | 
			
		||||
              var other = (this == $admin[index] ? $menu[index] : $admin[index]);
 | 
			
		||||
              if (!other.checked && confirm(Drupal.t('Also allow !name role to !permission?', {
 | 
			
		||||
                '!name': $roles[index].textContent,
 | 
			
		||||
                '!permission': (this == $admin[index] ? menuPermission : adminPermission)
 | 
			
		||||
              if (!other.checked && confirm(Drupal.t('Also allow @name role to @permission?', {
 | 
			
		||||
                '@name': $roles[index].textContent,
 | 
			
		||||
                '@permission': (this == $admin[index] ? menuPermission : adminPermission)
 | 
			
		||||
              }))) {
 | 
			
		||||
                other.checked = 'checked';
 | 
			
		||||
              }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Administration menu color override.
 | 
			
		||||
@@ -17,7 +16,7 @@
 | 
			
		||||
  border-right-color: #a91f1f;
 | 
			
		||||
}
 | 
			
		||||
#admin-menu ul li.admin-menu-tab a {
 | 
			
		||||
  border-right-color: #52565E;
 | 
			
		||||
  border-right-color: #52565e;
 | 
			
		||||
}
 | 
			
		||||
#admin-menu li li a {
 | 
			
		||||
  border-top-color: #801f1f;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Administration menu.
 | 
			
		||||
@@ -16,6 +15,7 @@
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  text-align: left;
 | 
			
		||||
  top: 0;
 | 
			
		||||
  height: 30px;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
}
 | 
			
		||||
#admin-menu-wrapper {
 | 
			
		||||
@@ -62,7 +62,7 @@ body.admin-menu {
 | 
			
		||||
#admin-menu li > span {
 | 
			
		||||
  background: transparent none;
 | 
			
		||||
  border: none;
 | 
			
		||||
  color: #EEE;
 | 
			
		||||
  color: #eee;
 | 
			
		||||
  font-weight: normal;
 | 
			
		||||
  text-align: left; /* LTR */
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
@@ -74,7 +74,7 @@ body.admin-menu {
 | 
			
		||||
  padding: 4px 8px;
 | 
			
		||||
}
 | 
			
		||||
#admin-menu .dropdown .admin-menu-tab a {
 | 
			
		||||
  border-right: 1px solid #52565E; /* LTR */
 | 
			
		||||
  border-right: 1px solid #52565e; /* LTR */
 | 
			
		||||
}
 | 
			
		||||
#admin-menu .dropdown li li a {
 | 
			
		||||
  border-right: none; /* LTR */
 | 
			
		||||
@@ -147,7 +147,7 @@ body.admin-menu {
 | 
			
		||||
 | 
			
		||||
/* Second-and-more-level hovering */
 | 
			
		||||
#admin-menu .dropdown li li.expandable {
 | 
			
		||||
  background: #45454A url(images/arrow.png) no-repeat 145px 6px;
 | 
			
		||||
  background: #45454a url(images/arrow.png) no-repeat 145px 6px;
 | 
			
		||||
}
 | 
			
		||||
#admin-menu .dropdown li li:hover {
 | 
			
		||||
  background-color: #111;
 | 
			
		||||
@@ -155,19 +155,19 @@ body.admin-menu {
 | 
			
		||||
#admin-menu .dropdown li li:hover a,
 | 
			
		||||
#admin-menu .dropdown li li:hover li:hover a,
 | 
			
		||||
#admin-menu .dropdown li li:hover li:hover li:hover a {
 | 
			
		||||
  color: #FFF;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
}
 | 
			
		||||
#admin-menu .dropdown li li.expandable:hover a,
 | 
			
		||||
#admin-menu .dropdown li li.expandable:hover li.expandable:hover a {
 | 
			
		||||
  border-color: #444;
 | 
			
		||||
  color: #EEE;
 | 
			
		||||
  color: #eee;
 | 
			
		||||
}
 | 
			
		||||
#admin-menu .dropdown li li.expandable:hover li a,
 | 
			
		||||
#admin-menu .dropdown li li.expandable:hover li.expandable:hover li a {
 | 
			
		||||
  border-color: #323232;
 | 
			
		||||
}
 | 
			
		||||
#admin-menu .dropdown li li:hover li a {
 | 
			
		||||
  color: #EEE;
 | 
			
		||||
  color: #eee;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Search form */
 | 
			
		||||
 
 | 
			
		||||
@@ -97,7 +97,7 @@ function admin_menu_tree_dynamic(array $expand_map) {
 | 
			
		||||
  $db_or = db_or();
 | 
			
		||||
  foreach ($plids as $path_plids) {
 | 
			
		||||
    $db_and = db_and();
 | 
			
		||||
    // plids with value 0 may be ignored.
 | 
			
		||||
    // Plids with value 0 may be ignored.
 | 
			
		||||
    foreach (array_filter($path_plids) as $column => $plid) {
 | 
			
		||||
      $db_and->condition($column, $plid);
 | 
			
		||||
    }
 | 
			
		||||
@@ -204,7 +204,7 @@ function admin_menu_merge_tree(array &$tree, array $tree_dynamic, array $expand_
 | 
			
		||||
        foreach ($load_functions as $index => $function) {
 | 
			
		||||
          if ($function) {
 | 
			
		||||
            if (is_array($function)) {
 | 
			
		||||
              list($function,) = each($function);
 | 
			
		||||
              $function = key($function);
 | 
			
		||||
            }
 | 
			
		||||
            // Add the loader function name minus "_load".
 | 
			
		||||
            $placeholder = '%' . substr($function, 0, -5);
 | 
			
		||||
@@ -269,7 +269,7 @@ function admin_menu_translate($router_item, $map) {
 | 
			
		||||
    // replace any other.
 | 
			
		||||
    // @todo Doing this instead leads to plenty of duplicate links below
 | 
			
		||||
    //   admin/structure/menu; likely a hidden recursion problem.
 | 
			
		||||
    // $router_item['mlid'] = $router_item['href'] . $router_item['mlid'];
 | 
			
		||||
    // $router_item['mlid'] = $router_item['href'] . $router_item['mlid'];.
 | 
			
		||||
    $router_item['mlid'] = $router_item['href'];
 | 
			
		||||
    // Turn menu callbacks into regular menu items to make them visible.
 | 
			
		||||
    if ($router_item['type'] == MENU_CALLBACK) {
 | 
			
		||||
@@ -278,10 +278,12 @@ function admin_menu_translate($router_item, $map) {
 | 
			
		||||
 | 
			
		||||
    // @see _menu_tree_check_access()
 | 
			
		||||
    $key = (50000 + $router_item['weight']) . ' ' . $router_item['title'] . ' ' . $router_item['mlid'];
 | 
			
		||||
    return array($key => array(
 | 
			
		||||
      'link' => $router_item,
 | 
			
		||||
      'below' => array(),
 | 
			
		||||
    ));
 | 
			
		||||
    return array(
 | 
			
		||||
      $key => array(
 | 
			
		||||
        'link' => $router_item,
 | 
			
		||||
        'below' => array(),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return array();
 | 
			
		||||
@@ -461,20 +463,22 @@ function admin_menu_links_icon() {
 | 
			
		||||
    '#access' => user_access('display drupal links'),
 | 
			
		||||
    '#href' => 'http://drupal.org',
 | 
			
		||||
  );
 | 
			
		||||
  // Add links to project issue queues.
 | 
			
		||||
  foreach (module_list(FALSE, TRUE) as $module) {
 | 
			
		||||
    $info = drupal_parse_info_file(drupal_get_path('module', $module) . '/' . $module . '.info');
 | 
			
		||||
    if (!isset($info['project']) || isset($links['icon']['drupal.org'][$info['project']])) {
 | 
			
		||||
      continue;
 | 
			
		||||
  if (variable_get('admin_menu_issue_queues', TRUE)) {
 | 
			
		||||
    // Add links to project issue queues.
 | 
			
		||||
    foreach (module_list(FALSE, TRUE) as $module) {
 | 
			
		||||
      $info = drupal_parse_info_file(drupal_get_path('module', $module) . '/' . $module . '.info');
 | 
			
		||||
      if (!isset($info['project']) || isset($links['icon']['drupal.org'][$info['project']])) {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
      $links['icon']['drupal.org'][$info['project']] = array(
 | 
			
		||||
        '#title' => t('@project issue queue', array('@project' => $info['name'])),
 | 
			
		||||
        '#weight' => ($info['project'] == 'drupal' ? -10 : 0),
 | 
			
		||||
        '#href' => 'http://drupal.org/project/issues/' . $info['project'],
 | 
			
		||||
        '#options' => array(
 | 
			
		||||
          'query' => array('version' => (isset($info['core']) ? $info['core'] : 'All')),
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    $links['icon']['drupal.org'][$info['project']] = array(
 | 
			
		||||
      '#title' => t('@project issue queue', array('@project' => $info['name'])),
 | 
			
		||||
      '#weight' => ($info['project'] == 'drupal' ? -10 : 0),
 | 
			
		||||
      '#href' => 'http://drupal.org/project/issues/' . $info['project'],
 | 
			
		||||
      '#options' => array(
 | 
			
		||||
        'query' => array('version' => (isset($info['core']) ? $info['core'] : 'All')),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  // Add items to flush caches.
 | 
			
		||||
  $links['icon']['flush-cache'] = array(
 | 
			
		||||
@@ -570,7 +574,7 @@ function admin_menu_links_users() {
 | 
			
		||||
    '#description' => t('Current anonymous / authenticated users'),
 | 
			
		||||
    '#weight' => -90,
 | 
			
		||||
    '#attributes' => array('class' => array('admin-menu-action', 'admin-menu-users')),
 | 
			
		||||
    '#href' => (user_access('administer users') ? 'admin/people/people' : 'user'),
 | 
			
		||||
    '#href' => (user_access('administer users') ? 'admin/people' : 'user'),
 | 
			
		||||
  );
 | 
			
		||||
  return $links;
 | 
			
		||||
}
 | 
			
		||||
@@ -658,7 +662,7 @@ function admin_menu_theme_settings() {
 | 
			
		||||
    '#default_value' => variable_get('admin_menu_tweak_modules', 0),
 | 
			
		||||
  );
 | 
			
		||||
  if (module_exists('util')) {
 | 
			
		||||
    $form['tweaks']['admin_menu_tweak_modules']['#description'] .= '<br /><strong>' . t('If the Utility module was installed for this purpose, it can be safely disabled and uninstalled.') . '</strong>';
 | 
			
		||||
    $form['tweaks']['admin_menu_tweak_modules']['#description'] = '<br /><strong>' . t('If the Utility module was installed for this purpose, it can be safely disabled and uninstalled.') . '</strong>';
 | 
			
		||||
  }
 | 
			
		||||
  $form['tweaks']['admin_menu_tweak_permissions'] = array(
 | 
			
		||||
    '#type' => 'checkbox',
 | 
			
		||||
@@ -685,6 +689,11 @@ function admin_menu_theme_settings() {
 | 
			
		||||
    '#title' => t('Cache menu in client-side browser'),
 | 
			
		||||
    '#default_value' => variable_get('admin_menu_cache_client', 1),
 | 
			
		||||
  );
 | 
			
		||||
  $form['performance']['admin_menu_issue_queues'] = array(
 | 
			
		||||
    '#type' => 'checkbox',
 | 
			
		||||
    '#title' => t('Show Issue Queue links in icon menu'),
 | 
			
		||||
    '#default_value' => variable_get('admin_menu_issue_queues', 1),
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return system_settings_form($form);
 | 
			
		||||
}
 | 
			
		||||
@@ -763,18 +772,20 @@ function admin_menu_flush_cache($name = NULL) {
 | 
			
		||||
    if (!isset($caches[$name])) {
 | 
			
		||||
      return MENU_NOT_FOUND;
 | 
			
		||||
    }
 | 
			
		||||
    $message = t('@title cache cleared.', array('@title' => $caches[$name]['title']));
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    $caches[$name] = array(
 | 
			
		||||
      'title' => t('Every'),
 | 
			
		||||
      'callback' => 'drupal_flush_all_caches',
 | 
			
		||||
    );
 | 
			
		||||
    $message = t('All caches cleared.');
 | 
			
		||||
  }
 | 
			
		||||
  // Pass the cache to flush forward to the callback.
 | 
			
		||||
  $function = $caches[$name]['callback'];
 | 
			
		||||
  $function($name);
 | 
			
		||||
 | 
			
		||||
  drupal_set_message(t('!title cache cleared.', array('!title' => $caches[$name]['title'])));
 | 
			
		||||
  drupal_set_message($message);
 | 
			
		||||
 | 
			
		||||
  // The JavaScript injects a destination request parameter pointing to the
 | 
			
		||||
  // originating page, so the user is redirected back to that page. Without
 | 
			
		||||
@@ -907,4 +918,3 @@ function template_preprocess_admin_menu_icon(&$variables) {
 | 
			
		||||
function theme_admin_menu_icon($variables) {
 | 
			
		||||
  return '<img class="admin-menu-icon" src="' . $variables['src'] . '" width="16" height="16" alt="' . $variables['alt'] . '" />';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,9 +8,8 @@ configure = admin/config/administration/admin_menu
 | 
			
		||||
dependencies[] = system (>7.10)
 | 
			
		||||
files[] = tests/admin_menu.test
 | 
			
		||||
 | 
			
		||||
; Information added by Drupal.org packaging script on 2014-12-19
 | 
			
		||||
version = "7.x-3.0-rc5"
 | 
			
		||||
; Information added by Drupal.org packaging script on 2018-12-03
 | 
			
		||||
version = "7.x-3.0-rc6"
 | 
			
		||||
core = "7.x"
 | 
			
		||||
project = "admin_menu"
 | 
			
		||||
datestamp = "1419029284"
 | 
			
		||||
 | 
			
		||||
datestamp = "1543859284"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,8 @@
 | 
			
		||||
(function($) {
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
(function ($) {
 | 
			
		||||
 | 
			
		||||
Drupal.admin = Drupal.admin || {};
 | 
			
		||||
Drupal.admin.behaviors = Drupal.admin.behaviors || {};
 | 
			
		||||
@@ -139,7 +143,7 @@ Drupal.admin.getCache = function (hash, onSuccess) {
 | 
			
		||||
 *
 | 
			
		||||
 * @see toolbar.js
 | 
			
		||||
 */
 | 
			
		||||
Drupal.admin.height = function() {
 | 
			
		||||
Drupal.admin.height = function () {
 | 
			
		||||
  var $adminMenu = $('#admin-menu');
 | 
			
		||||
  var height = $adminMenu.outerHeight();
 | 
			
		||||
  // In IE, Shadow filter adds some extra height, so we need to remove it from
 | 
			
		||||
@@ -161,7 +165,7 @@ Drupal.admin.height = function() {
 | 
			
		||||
Drupal.admin.attachBehaviors = function (context, settings, $adminMenu) {
 | 
			
		||||
  if ($adminMenu.length) {
 | 
			
		||||
    $adminMenu.addClass('admin-menu-processed');
 | 
			
		||||
    $.each(Drupal.admin.behaviors, function() {
 | 
			
		||||
    $.each(Drupal.admin.behaviors, function () {
 | 
			
		||||
      this(context, settings, $adminMenu);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
@@ -206,7 +210,7 @@ Drupal.admin.behaviors.replacements = function (context, settings, $adminMenu) {
 | 
			
		||||
 */
 | 
			
		||||
Drupal.admin.behaviors.destination = function (context, settings, $adminMenu) {
 | 
			
		||||
  if (settings.admin_menu.destination) {
 | 
			
		||||
    $('a.admin-menu-destination', $adminMenu).each(function() {
 | 
			
		||||
    $('a.admin-menu-destination', $adminMenu).each(function () {
 | 
			
		||||
      this.search += (!this.search.length ? '?' : '&') + Drupal.settings.admin_menu.destination;
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -80,7 +80,14 @@ function field_ui_admin_menu_map() {
 | 
			
		||||
        'access callback' => 'user_access',
 | 
			
		||||
        'access arguments' => array('administer site configuration'),
 | 
			
		||||
      );
 | 
			
		||||
      if (!call_user_func_array($bundle_info['admin']['access callback'], $bundle_info['admin']['access arguments'])) {
 | 
			
		||||
      $access_arguments = $bundle_info['admin']['access arguments'];
 | 
			
		||||
      if (isset($bundle_info['admin']['real path'])) {
 | 
			
		||||
        $menu_item = menu_get_item($bundle_info['admin']['real path']);
 | 
			
		||||
        if (isset($menu_item['map'])) {
 | 
			
		||||
          $access_arguments = menu_unserialize(serialize($access_arguments), $menu_item['map']);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (!call_user_func_array($bundle_info['admin']['access callback'], $access_arguments)) {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -63,7 +63,7 @@ function admin_menu_theme() {
 | 
			
		||||
function admin_menu_menu() {
 | 
			
		||||
  // AJAX callback.
 | 
			
		||||
  // @see http://drupal.org/project/js
 | 
			
		||||
  $items['js/admin_menu/cache'] = array(
 | 
			
		||||
  $items['js/admin_menu/cache/%'] = array(
 | 
			
		||||
    'page callback' => 'admin_menu_js_cache',
 | 
			
		||||
    'delivery callback' => 'admin_menu_deliver',
 | 
			
		||||
    'access arguments' => array('access administration menu'),
 | 
			
		||||
@@ -78,7 +78,7 @@ function admin_menu_menu() {
 | 
			
		||||
    'file' => 'system.admin.inc',
 | 
			
		||||
    'file path' => drupal_get_path('module', 'system'),
 | 
			
		||||
  );
 | 
			
		||||
  $items['admin/config/administration/admin_menu'] = array(
 | 
			
		||||
  $items['admin/config/administration/admin-menu'] = array(
 | 
			
		||||
    'title' => 'Administration menu',
 | 
			
		||||
    'description' => 'Adjust administration menu settings.',
 | 
			
		||||
    'page callback' => 'drupal_get_form',
 | 
			
		||||
@@ -211,7 +211,7 @@ function admin_menu_page_build(&$page) {
 | 
			
		||||
    // @todo Drupal.behaviors.adminMenuMarginTop is obsolete, but
 | 
			
		||||
    //   hook_page_build() does not allow to set a CSS class on the body yet.
 | 
			
		||||
    // @see http://drupal.org/node/1473548, http://drupal.org/node/1194528
 | 
			
		||||
    //$page['#attributes']['class'][] = 'admin-menu';
 | 
			
		||||
    // $page['#attributes']['class'][] = 'admin-menu';
 | 
			
		||||
  }
 | 
			
		||||
  if ($setting = variable_get('admin_menu_position_fixed', 1)) {
 | 
			
		||||
    $settings['position_fixed'] = $setting;
 | 
			
		||||
@@ -230,7 +230,7 @@ function admin_menu_page_build(&$page) {
 | 
			
		||||
  if ($_GET['q'] == 'admin/modules' || strpos($_GET['q'], 'admin/modules/list') === 0) {
 | 
			
		||||
    $settings['tweak_modules'] = variable_get('admin_menu_tweak_modules', 0);
 | 
			
		||||
  }
 | 
			
		||||
  if ($_GET['q'] == 'admin/people/permissions' || $_GET['q'] == 'admin/people/permissions/list') {
 | 
			
		||||
  if (strpos($_GET['q'], 'admin/people/permissions') === 0) {
 | 
			
		||||
    $settings['tweak_permissions'] = variable_get('admin_menu_tweak_permissions', 0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -502,7 +502,6 @@ function admin_menu_output($complete = FALSE) {
 | 
			
		||||
 | 
			
		||||
    // @todo Move the below callbacks into hook_admin_menu_build()
 | 
			
		||||
    //   implementations (and $module.admin_menu.inc).
 | 
			
		||||
 | 
			
		||||
    // Add administration menu.
 | 
			
		||||
    if (!empty($components['admin_menu.menu']) || $complete) {
 | 
			
		||||
      $content['menu'] = admin_menu_links_menu(admin_menu_tree('management'));
 | 
			
		||||
@@ -548,7 +547,10 @@ function admin_menu_output($complete = FALSE) {
 | 
			
		||||
 | 
			
		||||
  // Store the new hash for this user.
 | 
			
		||||
  if (!empty($_COOKIE['has_js']) && !$complete) {
 | 
			
		||||
    admin_menu_cache_set($cid, md5($content));
 | 
			
		||||
    $cache = cache_get($cid, 'cache_admin_menu');
 | 
			
		||||
    if (!$cache || !isset($cache->data)) {
 | 
			
		||||
      admin_menu_cache_set($cid, md5($content));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return $content;
 | 
			
		||||
@@ -603,11 +605,13 @@ function admin_menu_admin_menu_output_build(&$content) {
 | 
			
		||||
 * Implements hook_admin_menu_output_alter().
 | 
			
		||||
 */
 | 
			
		||||
function admin_menu_admin_menu_output_alter(&$content) {
 | 
			
		||||
  foreach ($content['menu'] as $key => $link) {
 | 
			
		||||
    // Move local tasks on 'admin' into icon menu.
 | 
			
		||||
    if ($key == 'admin/tasks' || $key == 'admin/index') {
 | 
			
		||||
      $content['icon']['icon'][$key] = $link;
 | 
			
		||||
      unset($content['menu'][$key]);
 | 
			
		||||
  if (!empty($content['menu'])) {
 | 
			
		||||
    foreach ($content['menu'] as $key => $link) {
 | 
			
		||||
      // Move local tasks on 'admin' into icon menu.
 | 
			
		||||
      if ($key == 'admin/tasks' || $key == 'admin/index') {
 | 
			
		||||
        $content['icon']['icon'][$key] = $link;
 | 
			
		||||
        unset($content['menu'][$key]);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -677,6 +681,13 @@ function theme_admin_menu_links($variables) {
 | 
			
		||||
        $elements[$path]['#options']['attributes']['class'][] = 'admin-menu-destination';
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // If the path has an alias replace the href with the alias.
 | 
			
		||||
      if (module_exists('path')) {
 | 
			
		||||
        if ($alias = drupal_get_path_alias($elements[$path]['#href'])) {
 | 
			
		||||
          $elements[$path]['#href'] = $alias;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      $link = l($elements[$path]['#title'], $elements[$path]['#href'], $elements[$path]['#options']);
 | 
			
		||||
    }
 | 
			
		||||
    // Handle plain text items, but do not interfere with menu additions.
 | 
			
		||||
@@ -751,7 +762,7 @@ function admin_menu_translated_menu_link_alter(&$item, $map) {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Don't waste cycles altering items that are not visible
 | 
			
		||||
  // Don't waste cycles altering items that are not visible.
 | 
			
		||||
  if (!$item['access']) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
@@ -795,8 +806,8 @@ function admin_menu_flush_caches($uid = NULL) {
 | 
			
		||||
  cache_clear_all($cid, 'cache_menu', TRUE);
 | 
			
		||||
  // Flush client-side cache hashes.
 | 
			
		||||
  drupal_static_reset('admin_menu_cache_get');
 | 
			
		||||
  // db_table_exists() required for SimpleTest.
 | 
			
		||||
  if (db_table_exists('cache_admin_menu')) {
 | 
			
		||||
  // If cache_admin_menu is not empty, flush it.
 | 
			
		||||
  if (!cache_is_empty('cache_admin_menu')) {
 | 
			
		||||
    cache_clear_all(isset($uid) ? $cid : '*', 'cache_admin_menu', TRUE);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Administration menu color override for uid1.
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,4 @@
 | 
			
		||||
#admin-menu > div > .dropdown > li > a,
 | 
			
		||||
#admin-menu > div > .dropdown > li > span {
 | 
			
		||||
  border-left: 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Toolbar style for Administration menu.
 | 
			
		||||
@@ -63,8 +62,9 @@ body div#toolbar.toolbar {
 | 
			
		||||
  background: url(toolbar.png) no-repeat 0 -45px;
 | 
			
		||||
  text-indent: -9999px;
 | 
			
		||||
}
 | 
			
		||||
#admin-menu > div > .dropdown > li > a {
 | 
			
		||||
  border-right: 0;
 | 
			
		||||
#admin-menu > div > .dropdown > li > a,
 | 
			
		||||
#admin-menu > div > .dropdown > li > span {
 | 
			
		||||
  border-right: 0; /* LTR */
 | 
			
		||||
  margin-bottom: 4px;
 | 
			
		||||
  padding: 2px 10px 3px;
 | 
			
		||||
}
 | 
			
		||||
@@ -142,4 +142,3 @@ body div#toolbar.toolbar {
 | 
			
		||||
#admin-menu .shortcut-toolbar a {
 | 
			
		||||
  display: block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,8 @@ package = Administration
 | 
			
		||||
core = 7.x
 | 
			
		||||
dependencies[] = admin_menu
 | 
			
		||||
 | 
			
		||||
; Information added by Drupal.org packaging script on 2014-12-19
 | 
			
		||||
version = "7.x-3.0-rc5"
 | 
			
		||||
; Information added by Drupal.org packaging script on 2018-12-03
 | 
			
		||||
version = "7.x-3.0-rc6"
 | 
			
		||||
core = "7.x"
 | 
			
		||||
project = "admin_menu"
 | 
			
		||||
datestamp = "1419029284"
 | 
			
		||||
 | 
			
		||||
datestamp = "1543859284"
 | 
			
		||||
 
 | 
			
		||||
@@ -34,4 +34,3 @@ function admin_menu_toolbar_update_6300() {
 | 
			
		||||
    ->condition('name', 'admin_menu_toolbar')
 | 
			
		||||
    ->execute();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -115,4 +115,3 @@ function admin_menu_toolbar_admin_menu_output_alter(&$content) {
 | 
			
		||||
    $content['account']['account']['#options']['html'] = TRUE;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,10 @@ class AdminMenuWebTestCase extends DrupalWebTestCase {
 | 
			
		||||
    'admin_menu' => 'access administration menu',
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  function setUp() {
 | 
			
		||||
  /**
 | 
			
		||||
   *
 | 
			
		||||
   */
 | 
			
		||||
  public function setUp() {
 | 
			
		||||
    // Enable admin menu module and any other modules.
 | 
			
		||||
    $modules = func_get_args();
 | 
			
		||||
    $modules = isset($modules[0]) ? $modules[0] : $modules;
 | 
			
		||||
@@ -108,12 +111,17 @@ class AdminMenuWebTestCase extends DrupalWebTestCase {
 | 
			
		||||
    $xpath = '//div[@id="admin-menu"]/div/ul' . implode('/parent::li/ul', $xpath);
 | 
			
		||||
    $this->assertNoElementByXPath($xpath, $args, $message . ' link not found.');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests menu links depending on user permissions.
 | 
			
		||||
 */
 | 
			
		||||
class AdminMenuPermissionsTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   *
 | 
			
		||||
   */
 | 
			
		||||
  public static function getInfo() {
 | 
			
		||||
    return array(
 | 
			
		||||
      'name' => 'Menu link access permissions',
 | 
			
		||||
@@ -122,14 +130,17 @@ class AdminMenuPermissionsTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function setUp() {
 | 
			
		||||
  /**
 | 
			
		||||
   *
 | 
			
		||||
   */
 | 
			
		||||
  public function setUp() {
 | 
			
		||||
    parent::setUp(array('node'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Test that the links are added to the page (no JS testing).
 | 
			
		||||
   */
 | 
			
		||||
  function testPermissions() {
 | 
			
		||||
  public function testPermissions() {
 | 
			
		||||
    module_enable(array('contact'));
 | 
			
		||||
    $this->resetAll();
 | 
			
		||||
 | 
			
		||||
@@ -140,7 +151,7 @@ class AdminMenuPermissionsTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
    // Create a user who
 | 
			
		||||
    // - can access content overview
 | 
			
		||||
    // - cannot access drupal.org links
 | 
			
		||||
    // - cannot administer Contact module
 | 
			
		||||
    // - cannot administer Contact module.
 | 
			
		||||
    $permissions = $this->basePermissions + array(
 | 
			
		||||
      'access content overview',
 | 
			
		||||
    );
 | 
			
		||||
@@ -156,7 +167,7 @@ class AdminMenuPermissionsTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
    // Create a user "reversed" to the above; i.e., who
 | 
			
		||||
    // - cannot access content overview
 | 
			
		||||
    // - can access drupal.org links
 | 
			
		||||
    // - can administer Contact module
 | 
			
		||||
    // - can administer Contact module.
 | 
			
		||||
    $permissions = $this->basePermissions + array(
 | 
			
		||||
      'display drupal links',
 | 
			
		||||
      'administer contact forms',
 | 
			
		||||
@@ -172,7 +183,7 @@ class AdminMenuPermissionsTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests handling of links pointing to category/overview pages.
 | 
			
		||||
   */
 | 
			
		||||
  function testCategories() {
 | 
			
		||||
  public function testCategories() {
 | 
			
		||||
    // Create a user with minimum permissions.
 | 
			
		||||
    $admin_user = $this->drupalCreateUser($this->basePermissions);
 | 
			
		||||
    $this->drupalLogin($admin_user);
 | 
			
		||||
@@ -201,7 +212,7 @@ class AdminMenuPermissionsTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests that user role and permission changes are properly taken up.
 | 
			
		||||
   */
 | 
			
		||||
  function testPermissionChanges() {
 | 
			
		||||
  public function testPermissionChanges() {
 | 
			
		||||
    // Create a user who is able to change permissions.
 | 
			
		||||
    $permissions = $this->basePermissions + array(
 | 
			
		||||
      'administer permissions',
 | 
			
		||||
@@ -253,12 +264,17 @@ class AdminMenuPermissionsTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
    // Verify that Structure » Content types does not appear.
 | 
			
		||||
    $this->assertNoLinkTrailByTitle(array(t('Structure'), t('Content types')));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests appearance, localization, and escaping of dynamic links.
 | 
			
		||||
 */
 | 
			
		||||
class AdminMenuDynamicLinksTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   *
 | 
			
		||||
   */
 | 
			
		||||
  public static function getInfo() {
 | 
			
		||||
    return array(
 | 
			
		||||
      'name' => 'Dynamic links',
 | 
			
		||||
@@ -267,14 +283,17 @@ class AdminMenuDynamicLinksTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function setUp() {
 | 
			
		||||
  /**
 | 
			
		||||
   *
 | 
			
		||||
   */
 | 
			
		||||
  public function setUp() {
 | 
			
		||||
    parent::setUp(array('node'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests node type links.
 | 
			
		||||
   */
 | 
			
		||||
  function testNode() {
 | 
			
		||||
  public function testNode() {
 | 
			
		||||
    $type = $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article'));
 | 
			
		||||
    // Create a content-type with special characters.
 | 
			
		||||
    $type = $this->drupalCreateContentType(array('type' => 'special', 'name' => 'Cool & Special'));
 | 
			
		||||
@@ -324,7 +343,7 @@ class AdminMenuDynamicLinksTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests Add content links.
 | 
			
		||||
   */
 | 
			
		||||
  function testNodeAdd() {
 | 
			
		||||
  public function testNodeAdd() {
 | 
			
		||||
    $type = $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article'));
 | 
			
		||||
 | 
			
		||||
    // Verify that "Add content" does not appear for unprivileged users.
 | 
			
		||||
@@ -359,12 +378,17 @@ class AdminMenuDynamicLinksTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
      t('Add content'),
 | 
			
		||||
    ));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests appearance of different types of links.
 | 
			
		||||
 */
 | 
			
		||||
class AdminMenuLinkTypesTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   *
 | 
			
		||||
   */
 | 
			
		||||
  public static function getInfo() {
 | 
			
		||||
    return array(
 | 
			
		||||
      'name' => 'Link types',
 | 
			
		||||
@@ -373,7 +397,10 @@ class AdminMenuLinkTypesTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function setUp() {
 | 
			
		||||
  /**
 | 
			
		||||
   *
 | 
			
		||||
   */
 | 
			
		||||
  public function setUp() {
 | 
			
		||||
    parent::setUp(array('help'));
 | 
			
		||||
 | 
			
		||||
    $permissions = module_invoke_all('permission');
 | 
			
		||||
@@ -385,7 +412,7 @@ class AdminMenuLinkTypesTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests appearance of different router item link types.
 | 
			
		||||
   */
 | 
			
		||||
  function testLinkTypes() {
 | 
			
		||||
  public function testLinkTypes() {
 | 
			
		||||
    // Verify that MENU_NORMAL_ITEMs appear.
 | 
			
		||||
    $this->assertLinkTrailByTitle(array(
 | 
			
		||||
      t('Configuration'),
 | 
			
		||||
@@ -420,12 +447,17 @@ class AdminMenuLinkTypesTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
      ':title' => t('Index'),
 | 
			
		||||
    ), "Icon » Index link found.");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests customized menu links.
 | 
			
		||||
 */
 | 
			
		||||
class AdminMenuCustomizedTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   *
 | 
			
		||||
   */
 | 
			
		||||
  public static function getInfo() {
 | 
			
		||||
    return array(
 | 
			
		||||
      'name' => 'Customized links',
 | 
			
		||||
@@ -434,7 +466,10 @@ class AdminMenuCustomizedTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function setUp() {
 | 
			
		||||
  /**
 | 
			
		||||
   *
 | 
			
		||||
   */
 | 
			
		||||
  public function setUp() {
 | 
			
		||||
    parent::setUp(array('menu'));
 | 
			
		||||
 | 
			
		||||
    $this->admin_user = $this->drupalCreateUser($this->basePermissions + array(
 | 
			
		||||
@@ -446,7 +481,7 @@ class AdminMenuCustomizedTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
  /**
 | 
			
		||||
   * Test disabled custom links.
 | 
			
		||||
   */
 | 
			
		||||
  function testCustomDisabled() {
 | 
			
		||||
  public function testCustomDisabled() {
 | 
			
		||||
    $type = $this->drupalCreateContentType();
 | 
			
		||||
    $node = $this->drupalCreateNode(array('type' => $type->type));
 | 
			
		||||
    $text = $this->randomName();
 | 
			
		||||
@@ -488,7 +523,7 @@ class AdminMenuCustomizedTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests external links.
 | 
			
		||||
   */
 | 
			
		||||
  function testCustomExternal() {
 | 
			
		||||
  public function testCustomExternal() {
 | 
			
		||||
    // Add a custom link to the node to the menu.
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'link_path' => 'http://example.com',
 | 
			
		||||
@@ -516,5 +551,5 @@ class AdminMenuCustomizedTestCase extends AdminMenuWebTestCase {
 | 
			
		||||
      ':path' => $path,
 | 
			
		||||
    ))->fetchField();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -465,12 +465,33 @@ function entity_translation_export_import_import_translation($data){
 | 
			
		||||
  $bundle = $data['Bundle (Not Editable)'];
 | 
			
		||||
  $entity_id = $data['Entity ID (Not Editable)'];
 | 
			
		||||
 | 
			
		||||
  $entities = entity_load($entity_type, array($entity_id));
 | 
			
		||||
  if(empty($entity_id)) {
 | 
			
		||||
    if ($entity_type == 'taxonomy_term') {
 | 
			
		||||
      // Handle taxonomy term entity.
 | 
			
		||||
      $vocab = taxonomy_vocabulary_machine_name_load($bundle);
 | 
			
		||||
      $term = new stdClass();
 | 
			
		||||
      $term->name = '';
 | 
			
		||||
      $term->vid = $vocab->vid;
 | 
			
		||||
      taxonomy_term_save($term);
 | 
			
		||||
 | 
			
		||||
  // If cannot load entity.
 | 
			
		||||
  if(empty($entities)){
 | 
			
		||||
    drupal_set_message(t('Entity with id @id could not be found in database.', array('@id' => $entity_id)));
 | 
			
		||||
    return FALSE;
 | 
			
		||||
      $entities = entity_load($entity_type, array($term->tid));
 | 
			
		||||
    }
 | 
			
		||||
    else if($entity_type == 'node') {
 | 
			
		||||
      // Handle node entity.
 | 
			
		||||
      $node = new stdClass();
 | 
			
		||||
      $node->type = $bundle;
 | 
			
		||||
      node_object_prepare($node);  //Set some default values
 | 
			
		||||
      $node->status = 1;
 | 
			
		||||
      $node->promote = 0;
 | 
			
		||||
      $node->sticky = 0;
 | 
			
		||||
      $node->uid = $user->uid;
 | 
			
		||||
     node_save($node);
 | 
			
		||||
 | 
			
		||||
     $entities = entity_load($entity_type, array($node->nid));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    $entities = entity_load($entity_type, array($entity_id));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Get the entity.
 | 
			
		||||
 
 | 
			
		||||
@@ -5,9 +5,9 @@ package = Multilingual - Entity Translation
 | 
			
		||||
dependencies[] = entity
 | 
			
		||||
dependencies[] = entity_translation
 | 
			
		||||
 | 
			
		||||
; Information added by drupal.org packaging script on 2013-09-30
 | 
			
		||||
version = "7.x-1.0-beta3+0-dev"
 | 
			
		||||
; Information added by Drupal.org packaging script on 2017-02-08
 | 
			
		||||
version = "7.x-1.0-beta4"
 | 
			
		||||
core = "7.x"
 | 
			
		||||
project = "entity_translation_export_import"
 | 
			
		||||
datestamp = "1380577025"
 | 
			
		||||
datestamp = "1486567689"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,13 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Webform Component information for an address field type
 | 
			
		||||
 * Webform Component information for an address field type.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Specify the default properties of a component.
 | 
			
		||||
 *
 | 
			
		||||
 * @return
 | 
			
		||||
 * @return array
 | 
			
		||||
 *   An array defining the default structure of a component.
 | 
			
		||||
 */
 | 
			
		||||
function _webform_defaults_addressfield() {
 | 
			
		||||
@@ -23,6 +23,8 @@ function _webform_defaults_addressfield() {
 | 
			
		||||
      'attributes'                => array(),
 | 
			
		||||
      'description'               => '',
 | 
			
		||||
      'available_countries'       => array(),
 | 
			
		||||
      'default_country'           => '',
 | 
			
		||||
      'format_handlers'           => array(),
 | 
			
		||||
      'csv_separate'              => 0,
 | 
			
		||||
    ),
 | 
			
		||||
  );
 | 
			
		||||
@@ -30,21 +32,22 @@ function _webform_defaults_addressfield() {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generate the form for editing a component.
 | 
			
		||||
 *
 | 
			
		||||
 * Create a set of form elements to be displayed on the form for editing this
 | 
			
		||||
 * component. Use care naming the form items, as this correlates directly to the
 | 
			
		||||
 * database schema. The component "Name" and "Description" fields are added to
 | 
			
		||||
 * every component type and are not necessary to specify here (although they
 | 
			
		||||
 * may be overridden if desired).
 | 
			
		||||
 *
 | 
			
		||||
 * @param $component
 | 
			
		||||
 * @param mixed $component
 | 
			
		||||
 *   A Webform component array.
 | 
			
		||||
 *
 | 
			
		||||
 * @return
 | 
			
		||||
 * @return array
 | 
			
		||||
 *   An array of form items to be displayed on the edit component page
 | 
			
		||||
 */
 | 
			
		||||
function _webform_edit_addressfield($component) {
 | 
			
		||||
  $form = array();
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  $form['extra']['available_countries'] = array(
 | 
			
		||||
    '#type' => 'select',
 | 
			
		||||
    '#multiple' => TRUE,
 | 
			
		||||
@@ -53,6 +56,21 @@ function _webform_edit_addressfield($component) {
 | 
			
		||||
    '#options' => _addressfield_country_options_list(),
 | 
			
		||||
    '#default_value' => $component['extra']['available_countries'],
 | 
			
		||||
  );
 | 
			
		||||
  $form['extra']['default_country'] = array(
 | 
			
		||||
    '#type' => 'select',
 | 
			
		||||
    '#multiple' => FALSE,
 | 
			
		||||
    '#title' => t('Default country'),
 | 
			
		||||
    '#description' => t('Select which country should be selected as the default.'),
 | 
			
		||||
    '#options' => array_merge(array(0 => t('- None -')), _addressfield_country_options_list()),
 | 
			
		||||
    '#default_value' => $component['extra']['default_country'],
 | 
			
		||||
  );
 | 
			
		||||
  $form['extra']['format_handlers'] = array(
 | 
			
		||||
    '#type' => 'checkboxes',
 | 
			
		||||
    '#title' => t('Format handlers'),
 | 
			
		||||
    '#options' => addressfield_format_plugins_options(),
 | 
			
		||||
    '#required' => TRUE,
 | 
			
		||||
    '#default_value' => !empty($component['extra']['format_handlers']) ? $component['extra']['format_handlers'] : array('address'),
 | 
			
		||||
  );
 | 
			
		||||
  $form['extra']['csv_separate'] = array(
 | 
			
		||||
    '#type' => 'radios',
 | 
			
		||||
    '#title' => t('CSV download'),
 | 
			
		||||
@@ -69,18 +87,21 @@ function _webform_edit_addressfield($component) {
 | 
			
		||||
/**
 | 
			
		||||
 * Render a Webform component to be part of a form.
 | 
			
		||||
 *
 | 
			
		||||
 * @param $component
 | 
			
		||||
 * @param mixed $component
 | 
			
		||||
 *   A Webform component array.
 | 
			
		||||
 * @param $value
 | 
			
		||||
 * @param mixed $value
 | 
			
		||||
 *   If editing an existing submission or resuming a draft, this will contain
 | 
			
		||||
 *   an array of values to be shown instead of the default in the component
 | 
			
		||||
 *   configuration. This value will always be an array, keyed numerically for
 | 
			
		||||
 *   each value saved in this field.
 | 
			
		||||
 * @param $filter
 | 
			
		||||
 * @param bool $filter
 | 
			
		||||
 *   Whether or not to filter the contents of descriptions and values when
 | 
			
		||||
 *   rendering the component. Values need to be unfiltered to be editable by
 | 
			
		||||
 *   Form Builder.
 | 
			
		||||
 *
 | 
			
		||||
 * @return array
 | 
			
		||||
 *   Form element.
 | 
			
		||||
 *
 | 
			
		||||
 * @see _webform_client_form_add_component()
 | 
			
		||||
 */
 | 
			
		||||
function _webform_render_addressfield($component, $value = NULL, $filter = TRUE) {
 | 
			
		||||
@@ -98,55 +119,98 @@ function _webform_render_addressfield($component, $value = NULL, $filter = TRUE)
 | 
			
		||||
      'description',
 | 
			
		||||
    ),
 | 
			
		||||
  );
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  $available = !empty($component['extra']['available_countries']) ? $component['extra']['available_countries'] : NULL;
 | 
			
		||||
    
 | 
			
		||||
  // Get the current address
 | 
			
		||||
  if (!empty($value[0])) {
 | 
			
		||||
    if (is_string($value[0])) {
 | 
			
		||||
      $address = unserialize($value[0]);
 | 
			
		||||
 | 
			
		||||
  // Get the current address.
 | 
			
		||||
  $address = _addressfield_tokens_expand_value($value);
 | 
			
		||||
  if (empty($address)) {
 | 
			
		||||
    if (!empty($component['value'])) {
 | 
			
		||||
      $address = $component['value'];
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      $address = $value[0];
 | 
			
		||||
      $address = _webform_addressfield($component['cid']);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  elseif (!empty($component['value'])) {
 | 
			
		||||
    $address = $component['value'];
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    $address = _webform_addressfield($component['cid']);
 | 
			
		||||
  }
 | 
			
		||||
  if (empty($address)) {
 | 
			
		||||
    $address = addressfield_default_values($available);
 | 
			
		||||
    $address = _webform_addressfield_default_values($available, $component);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  // Generate the address form.
 | 
			
		||||
  $context = array(
 | 
			
		||||
    'mode' => 'form',
 | 
			
		||||
    'instance' => array(
 | 
			
		||||
      'required' => $component['required'],
 | 
			
		||||
    ),
 | 
			
		||||
    'form_key' => $component['form_key'],
 | 
			
		||||
  );
 | 
			
		||||
  $element += addressfield_generate($address, array('address'), $context);
 | 
			
		||||
  
 | 
			
		||||
  if (!empty($available)) {
 | 
			
		||||
    $element['country']['#options'] = array_intersect_key($element['country']['#options'], $available);
 | 
			
		||||
  $handlers = !empty($component['extra']['format_handlers']) ? $component['extra']['format_handlers'] : array('address');
 | 
			
		||||
  $element += addressfield_generate($address, $handlers, $context);
 | 
			
		||||
 | 
			
		||||
  if (empty($address['country'])) {
 | 
			
		||||
    $element['street_block']['#access'] = FALSE;
 | 
			
		||||
    $element['locality_block']['#access'] = FALSE;
 | 
			
		||||
  }
 | 
			
		||||
  $element['country']['#element_validate'] = array('_webform_addressfield_country_validate');
 | 
			
		||||
  $element['country']['#cid'] = $component['cid'];
 | 
			
		||||
  $element['country']['#limit_validation_errors'] = array();
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  if (isset($element['country'])) {
 | 
			
		||||
    if (!empty($available)) {
 | 
			
		||||
      $element['country']['#options'] = array_intersect_key($element['country']['#options'], $available);
 | 
			
		||||
 | 
			
		||||
      // Hide the country element only if there is one option and the whole field
 | 
			
		||||
      // is required, otherwise there will always be an additional None option.
 | 
			
		||||
      // @see addressfield_format_address_hide_country()
 | 
			
		||||
      if (!empty($handlers['address-hide-country']) && count($element['country']['#options']) == 1 && $component['required']) {
 | 
			
		||||
        $element['country']['#access'] =  FALSE;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    $element['country']['#default_value'] = $address['country'];
 | 
			
		||||
    $element['country']['#element_validate'] = array('_webform_addressfield_country_validate');
 | 
			
		||||
    $element['country']['#cid'] = $component['cid'];
 | 
			
		||||
    $element['country']['#limit_validation_errors'] = array();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  $form_state = array();
 | 
			
		||||
  drupal_alter('field_widget_addressfield_standard_form', $element, $form_state, $context); 
 | 
			
		||||
  
 | 
			
		||||
  drupal_alter('field_widget_addressfield_standard_form', $element, $form_state, $context);
 | 
			
		||||
 | 
			
		||||
  return $element;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _webform_addressfield_default_values($available, $component) {
 | 
			
		||||
  $default_country = !empty($component['extra']['default_country'])
 | 
			
		||||
    ? $component['extra']['default_country']
 | 
			
		||||
    : addressfield_tokens_default_country();
 | 
			
		||||
  $default_values = array(
 | 
			
		||||
    'country' => $default_country,
 | 
			
		||||
    'name_line' => '',
 | 
			
		||||
    'first_name' => '',
 | 
			
		||||
    'last_name' => '',
 | 
			
		||||
    'organisation_name' => '',
 | 
			
		||||
    'administrative_area' => '',
 | 
			
		||||
    'sub_administrative_area' => '',
 | 
			
		||||
    'locality' => '',
 | 
			
		||||
    'dependent_locality' => '',
 | 
			
		||||
    'postal_code' => '',
 | 
			
		||||
    'thoroughfare' => '',
 | 
			
		||||
    'premise' => '',
 | 
			
		||||
    'sub_premise' => '',
 | 
			
		||||
    'data' => '',
 | 
			
		||||
  );
 | 
			
		||||
  return ($default_values);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Stores an addressfield submitted in a webform component.  Ideally we should store
 | 
			
		||||
 * it in the $form_state instead, but there appears to be no way to get it to actually
 | 
			
		||||
 * pass through to _webform_render_addressfield().
 | 
			
		||||
 * 
 | 
			
		||||
 * @param $cid integer The ID of the webform component.
 | 
			
		||||
 * @param $address array If set, this address will be stored with the given $cid.
 | 
			
		||||
 * @return array The address stored with the given $cid, if there is one; otherwise, NULL.
 | 
			
		||||
 * Stores an addressfield submitted in a webform component.
 | 
			
		||||
 *
 | 
			
		||||
 * Ideally store it in the $form_state instead, but there appears to be no way
 | 
			
		||||
 * to get it to actually pass through to _webform_render_addressfield().
 | 
			
		||||
 *
 | 
			
		||||
 * @param int $cid
 | 
			
		||||
 *   The ID of the webform component.
 | 
			
		||||
 * @param mixed $address
 | 
			
		||||
 *   If set, this address will be stored with the given $cid.
 | 
			
		||||
 *
 | 
			
		||||
 * @return array
 | 
			
		||||
 *   The address stored with the given $cid, if there is one; otherwise, NULL.
 | 
			
		||||
 */
 | 
			
		||||
function _webform_addressfield($cid, $address = NULL) {
 | 
			
		||||
  $out = &drupal_static(__FUNCTION__, array());
 | 
			
		||||
@@ -160,40 +224,41 @@ function _webform_addressfield($cid, $address = NULL) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Validates a country, and if it changes, rebuilds the form for the new country
 | 
			
		||||
 * Validates a country, and if changed, rebuilds the form for the new country.
 | 
			
		||||
 */
 | 
			
		||||
function _webform_addressfield_country_validate(&$element, &$form_state) {
 | 
			
		||||
  // If the country was changed, rebuild the form.
 | 
			
		||||
  if ($element['#default_value'] != $element['#value']) {
 | 
			
		||||
  if (!isset($element['#default_value']) || $element['#default_value'] != $element['#value']) {
 | 
			
		||||
    $form_state['rebuild'] = TRUE;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  $cid = $element['#cid'];
 | 
			
		||||
  $parents = $element['#parents'];
 | 
			
		||||
  array_pop($parents);
 | 
			
		||||
 | 
			
		||||
  // Search through the form values to find the current address.
 | 
			
		||||
  $address = drupal_array_get_nested_value($form_state['values'], $parents);
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  _webform_addressfield($cid, $address);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Display the result of a submission for a component.
 | 
			
		||||
 *
 | 
			
		||||
 * The output of this function will be displayed under the "Results" tab then
 | 
			
		||||
 * "Submissions". This should output the saved data in some reasonable manner.
 | 
			
		||||
 *
 | 
			
		||||
 * @param $component
 | 
			
		||||
 * @param mixed $component
 | 
			
		||||
 *   A Webform component array.
 | 
			
		||||
 * @param $value
 | 
			
		||||
 * @param mixed $value
 | 
			
		||||
 *   An array of information containing the submission result, directly
 | 
			
		||||
 *   correlating to the webform_submitted_data database table schema.
 | 
			
		||||
 * @param $format
 | 
			
		||||
 * @param string $format
 | 
			
		||||
 *   Either 'html' or 'text'. Defines the format that the content should be
 | 
			
		||||
 *   returned as. Make sure that returned content is run through check_plain()
 | 
			
		||||
 *   or other filtering functions when returning HTML.
 | 
			
		||||
 *
 | 
			
		||||
 * @return
 | 
			
		||||
 * @return array
 | 
			
		||||
 *   A renderable element containing at the very least these properties:
 | 
			
		||||
 *    - #title
 | 
			
		||||
 *    - #weight
 | 
			
		||||
@@ -205,27 +270,23 @@ function _webform_addressfield_country_validate(&$element, &$form_state) {
 | 
			
		||||
 *   (such as wrapping the text) or as HTML (ensuring consistent output).
 | 
			
		||||
 */
 | 
			
		||||
function _webform_display_addressfield($component, $value, $format = 'html') {
 | 
			
		||||
  $address = NULL;
 | 
			
		||||
  if (isset($value[0])) {
 | 
			
		||||
    $address = $value[0];
 | 
			
		||||
    if (is_string($address)) {
 | 
			
		||||
      $address = unserialize($address);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  $address = _addressfield_tokens_expand_value($value);
 | 
			
		||||
  return array(
 | 
			
		||||
    '#title'          => $component['name'],
 | 
			
		||||
    '#weight'         => $component['weight'],
 | 
			
		||||
    '#theme'          => $format == 'html' ? 'addressfield_formatter' : 'addressfield_formatter__linear',
 | 
			
		||||
    '#theme_wrappers' => $format == 'html' ? array('webform_element' ) : array('webform_element_text'),
 | 
			
		||||
    '#theme_wrappers' => $format == 'html' ? array('webform_element') : array('webform_element_text'),
 | 
			
		||||
    '#post_render'    => array('webform_element_wrapper'),
 | 
			
		||||
    '#component'      => $component,
 | 
			
		||||
    '#format'         => $format,
 | 
			
		||||
    '#address'        => $address,
 | 
			
		||||
    '#address'        => $address ? $address : NULL,
 | 
			
		||||
    '#handlers'       => $component['extra']['format_handlers'],
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A hook for changing the input values before saving to the database.
 | 
			
		||||
 *
 | 
			
		||||
 * Webform expects a component to consist of a single field, or a single array
 | 
			
		||||
 * of fields. If you have a component that requires a deeper form tree
 | 
			
		||||
 * you must flatten the data into a single array using this callback
 | 
			
		||||
@@ -234,12 +295,12 @@ function _webform_display_addressfield($component, $value, $format = 'html') {
 | 
			
		||||
 * Note that Webform will save the result of this function directly into the
 | 
			
		||||
 * database.
 | 
			
		||||
 *
 | 
			
		||||
 * @param $component
 | 
			
		||||
 * @param mixed $component
 | 
			
		||||
 *   A Webform component array.
 | 
			
		||||
 * @param $value
 | 
			
		||||
 * @param mixed $value
 | 
			
		||||
 *   The POST data associated with the user input.
 | 
			
		||||
 *
 | 
			
		||||
 * @return
 | 
			
		||||
 * @return array
 | 
			
		||||
 *   An array of values to be saved into the database. Note that this should be
 | 
			
		||||
 *   a numerically keyed array.
 | 
			
		||||
 */
 | 
			
		||||
@@ -249,88 +310,92 @@ function _webform_submit_addressfield($component, $value) {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Calculate and returns statistics about results for this component.
 | 
			
		||||
 *
 | 
			
		||||
 * This takes into account all submissions to this webform. The output of this
 | 
			
		||||
 * function will be displayed under the "Results" tab then "Analysis".
 | 
			
		||||
 *
 | 
			
		||||
 * @param $component
 | 
			
		||||
 * @param mixed $component
 | 
			
		||||
 *   An array of information describing the component, directly correlating to
 | 
			
		||||
 *   the webform_component database schema.
 | 
			
		||||
 * @param $sids
 | 
			
		||||
 * @param mixed $sids
 | 
			
		||||
 *   An optional array of submission IDs (sid). If supplied, the analysis will
 | 
			
		||||
 *   be limited to these sids.
 | 
			
		||||
 * @param $single
 | 
			
		||||
 * @param bool $single
 | 
			
		||||
 *   Boolean flag determining if the details about a single component are being
 | 
			
		||||
 *   shown. May be used to provided detailed information about a single
 | 
			
		||||
 *   component's analysis, such as showing "Other" options within a select list.
 | 
			
		||||
 *
 | 
			
		||||
 * @return
 | 
			
		||||
 * @return array
 | 
			
		||||
 *   An array of data rows, each containing a statistic for this component's
 | 
			
		||||
 *   submissions.
 | 
			
		||||
 */
 | 
			
		||||
function _webform_analysis_addressfield($component, $sids = array(), $single = FALSE) {
 | 
			
		||||
  // TODO Update this function
 | 
			
		||||
  
 | 
			
		||||
  // @todo Update this function
 | 
			
		||||
 | 
			
		||||
  // Generate the list of options and questions.
 | 
			
		||||
  $query = db_select('webform_submitted_data', 'wsd')
 | 
			
		||||
    ->fields('wsd', array('data'))
 | 
			
		||||
    ->condition('nid', $component['nid'])
 | 
			
		||||
    ->condition('cid', $component['cid']);
 | 
			
		||||
    
 | 
			
		||||
  if ( count($sids) ) {
 | 
			
		||||
 | 
			
		||||
  if (count($sids)) {
 | 
			
		||||
    $query->condition('sid', $sids, 'IN');
 | 
			
		||||
  }
 | 
			
		||||
  $non_blanks = 0;
 | 
			
		||||
  $submissions = 0;
 | 
			
		||||
  $results = $query->execute();
 | 
			
		||||
  foreach ($results as $row) {
 | 
			
		||||
    if ( drupal_strlen(trim($row->data)) > 0 ) {
 | 
			
		||||
    if (drupal_strlen(trim($row->data)) > 0) {
 | 
			
		||||
      $non_blanks++;
 | 
			
		||||
    }
 | 
			
		||||
    $submissions++;
 | 
			
		||||
  }
 | 
			
		||||
  $rows[0] = array(
 | 
			
		||||
    t('Left Blank'),
 | 
			
		||||
    ( $submissions - $non_blanks )
 | 
			
		||||
    ($submissions - $non_blanks),
 | 
			
		||||
  );
 | 
			
		||||
  $rows[1] = array(
 | 
			
		||||
    t('User entered value'),
 | 
			
		||||
    $non_blanks
 | 
			
		||||
    $non_blanks,
 | 
			
		||||
  );
 | 
			
		||||
  return $rows;
 | 
			
		||||
  return array('table_rows' => $rows);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Return the result of a component value for display in a table.
 | 
			
		||||
 *
 | 
			
		||||
 * The output of this function will be displayed under the "Results" tab then
 | 
			
		||||
 * "Table".
 | 
			
		||||
 *
 | 
			
		||||
 * @param $component
 | 
			
		||||
 * @param mixed $component
 | 
			
		||||
 *   A Webform component array.
 | 
			
		||||
 * @param $value
 | 
			
		||||
 * @param mixed $value
 | 
			
		||||
 *   An array of information containing the submission result, directly
 | 
			
		||||
 *   correlating to the webform_submitted_data database schema.
 | 
			
		||||
 *
 | 
			
		||||
 * @return
 | 
			
		||||
 * @return string
 | 
			
		||||
 *   Textual output formatted for human reading.
 | 
			
		||||
 */
 | 
			
		||||
function _webform_table_addressfield($component, $value) {
 | 
			
		||||
  if (!empty($value[0])) {
 | 
			
		||||
    return theme('addressfield_formatter', array( 'address' => $value[0] ));
 | 
			
		||||
  $address = _addressfield_tokens_expand_value($value);
 | 
			
		||||
  if ($address) {
 | 
			
		||||
    return theme('addressfield_formatter', array('address' => $address));
 | 
			
		||||
  }
 | 
			
		||||
  return '';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Return the header for this component to be displayed in a CSV file.
 | 
			
		||||
 *
 | 
			
		||||
 * The output of this function will be displayed under the "Results" tab then
 | 
			
		||||
 * "Download".
 | 
			
		||||
 *
 | 
			
		||||
 * @param $component
 | 
			
		||||
 * @param mixed $component
 | 
			
		||||
 *   A Webform component array.
 | 
			
		||||
 * @param $export_options
 | 
			
		||||
 * @param mixed $export_options
 | 
			
		||||
 *   An array of options that may configure export of this field.
 | 
			
		||||
 *
 | 
			
		||||
 * @return
 | 
			
		||||
 * @return array
 | 
			
		||||
 *   An array of data to be displayed in the first three rows of a CSV file, not
 | 
			
		||||
 *   including either prefixed or trailing commas.
 | 
			
		||||
 */
 | 
			
		||||
@@ -340,7 +405,6 @@ function _webform_csv_headers_addressfield($component, $export_options) {
 | 
			
		||||
    $header[0] = array();
 | 
			
		||||
    $header[1] = array();
 | 
			
		||||
    $header[2] = array();
 | 
			
		||||
    
 | 
			
		||||
    foreach (addressfield_tokens_property_names() as $key => $name) {
 | 
			
		||||
      $header[0][] = '';
 | 
			
		||||
      $header[1][] = (empty($header[1])) ? $component['name'] : '';
 | 
			
		||||
@@ -349,7 +413,7 @@ function _webform_csv_headers_addressfield($component, $export_options) {
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    $header[0] = array('');
 | 
			
		||||
    $header[1] = array();
 | 
			
		||||
    $header[1] = array('');
 | 
			
		||||
    $header[2] = array($component['name']);
 | 
			
		||||
  }
 | 
			
		||||
  return $header;
 | 
			
		||||
@@ -357,34 +421,56 @@ function _webform_csv_headers_addressfield($component, $export_options) {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Format the submitted data of a component for CSV downloading.
 | 
			
		||||
 *
 | 
			
		||||
 * The output of this function will be displayed under the "Results" tab then
 | 
			
		||||
 * "Download".
 | 
			
		||||
 *
 | 
			
		||||
 * @param $component
 | 
			
		||||
 * @param mixed $component
 | 
			
		||||
 *   A Webform component array.
 | 
			
		||||
 * @param $export_options
 | 
			
		||||
 * @param mixed $export_options
 | 
			
		||||
 *   An array of options that may configure export of this field.
 | 
			
		||||
 * @param $value
 | 
			
		||||
 * @param mixed $value
 | 
			
		||||
 *   An array of information containing the submission result, directly
 | 
			
		||||
 *   correlating to the webform_submitted_data database schema.
 | 
			
		||||
 *
 | 
			
		||||
 * @return
 | 
			
		||||
 * @return array
 | 
			
		||||
 *   An array of items to be added to the CSV file. Each value within the array
 | 
			
		||||
 *   will be another column within the file. This function is called once for
 | 
			
		||||
 *   every row of data.
 | 
			
		||||
 */
 | 
			
		||||
function _webform_csv_data_addressfield($component, $export_options, $value) {
 | 
			
		||||
  $address = _addressfield_tokens_expand_value($value);
 | 
			
		||||
  if (!empty($component['extra']['csv_separate']) && $component['extra']['csv_separate'] == 1) {
 | 
			
		||||
    // Each address component should be in a separate column.
 | 
			
		||||
    $return = array();
 | 
			
		||||
    foreach (addressfield_tokens_property_names() as $key => $name) {
 | 
			
		||||
      $return[] = (isset($value[0][$key])) ? $value[0][$key] : '';
 | 
			
		||||
      $return[] = (isset($address[$key])) ? $address[$key] : '';
 | 
			
		||||
    }
 | 
			
		||||
    return $return;
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    if (!empty($value[0])) {
 | 
			
		||||
      return theme('addressfield_formatter__linear', array( 'address' => $value[0] ));
 | 
			
		||||
    // The entire address should be displayed in the one column.
 | 
			
		||||
    if ($address) {
 | 
			
		||||
      return theme('addressfield_formatter__linear', array('address' => $address));
 | 
			
		||||
    }
 | 
			
		||||
    return '';
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Expand a raw address submission as loaded from the database to an array.
 | 
			
		||||
 *
 | 
			
		||||
 * @param string $value
 | 
			
		||||
 *   An array of information containing the submission result, directly
 | 
			
		||||
 *   correlating to the {webform_submitted_data} database schema.
 | 
			
		||||
 *
 | 
			
		||||
 * @return array|false
 | 
			
		||||
 *   An associative array of address fields, or FALSE on failure.
 | 
			
		||||
 */
 | 
			
		||||
function _addressfield_tokens_expand_value($value) {
 | 
			
		||||
  if (isset($value[0]) && is_string($value[0])) {
 | 
			
		||||
    return unserialize($value[0]);
 | 
			
		||||
  }
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,16 +1,13 @@
 | 
			
		||||
 | 
			
		||||
name = Address Field Tokens
 | 
			
		||||
description = Creates tokens for address fields, adds new addressfield renders, and adds webform integration.
 | 
			
		||||
core = 7.x
 | 
			
		||||
package = Fields
 | 
			
		||||
 | 
			
		||||
dependencies[] = addressfield
 | 
			
		||||
dependencies[] = entity_token
 | 
			
		||||
dependencies[] = token
 | 
			
		||||
name = Address Field Tokens
 | 
			
		||||
description = Creates tokens for address fields, adds new addressfield renders, and adds webform integration.
 | 
			
		||||
core = 7.x
 | 
			
		||||
package = Fields
 | 
			
		||||
dependencies[] = addressfield
 | 
			
		||||
dependencies[] = entity_token
 | 
			
		||||
dependencies[] = token
 | 
			
		||||
 | 
			
		||||
; Information added by Drupal.org packaging script on 2014-10-29
 | 
			
		||||
version = "7.x-1.5"
 | 
			
		||||
; Information added by Drupal.org packaging script on 2018-10-11
 | 
			
		||||
version = "7.x-1.13"
 | 
			
		||||
core = "7.x"
 | 
			
		||||
project = "addressfield_tokens"
 | 
			
		||||
datestamp = "1414599829"
 | 
			
		||||
 | 
			
		||||
datestamp = "1539260884"
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,12 @@
 | 
			
		||||
 * Main components.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_menu().
 | 
			
		||||
 */
 | 
			
		||||
function addressfield_tokens_menu() {
 | 
			
		||||
  $items = array();
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  $items['admin/config/regional/address'] = array(
 | 
			
		||||
    'title' => 'Addresses',
 | 
			
		||||
    'description' => 'Settings for address fields and tokens',
 | 
			
		||||
@@ -16,7 +19,7 @@ function addressfield_tokens_menu() {
 | 
			
		||||
    'file' => 'addressfield_tokens.admin.inc',
 | 
			
		||||
    'type' => MENU_NORMAL_ITEM,
 | 
			
		||||
  );
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  return $items;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -34,19 +37,31 @@ function addressfield_tokens_theme($existing, $type, $theme, $path) {
 | 
			
		||||
      'file' => 'addressfield_tokens.theme.inc',
 | 
			
		||||
    ),
 | 
			
		||||
    'addressfield_formatter__linear' => array(
 | 
			
		||||
      'variables' => array('address' => NULL, 'premise' => TRUE, 'organisation_name' => TRUE, 'name_line' => TRUE),
 | 
			
		||||
      'variables' => array(
 | 
			
		||||
        'address' => NULL,
 | 
			
		||||
        'premise' => TRUE,
 | 
			
		||||
        'organisation_name' => TRUE,
 | 
			
		||||
        'name_line' => TRUE,
 | 
			
		||||
      ),
 | 
			
		||||
      'file' => 'addressfield_tokens.theme.inc',
 | 
			
		||||
    ),
 | 
			
		||||
    'addressfield_formatter__components' => array(
 | 
			
		||||
      'variables' => array(
 | 
			
		||||
        'address' => NULL,
 | 
			
		||||
        'components' => array('thoroughfare', 'premise', 'locality', 'administrative_area', 'postal_code', 'country'),
 | 
			
		||||
        'components' => array(
 | 
			
		||||
          'thoroughfare',
 | 
			
		||||
          'premise',
 | 
			
		||||
          'locality',
 | 
			
		||||
          'administrative_area',
 | 
			
		||||
          'postal_code',
 | 
			
		||||
          'country',
 | 
			
		||||
        ),
 | 
			
		||||
        'separator' => ', ',
 | 
			
		||||
      ),
 | 
			
		||||
      'file' => 'addressfield_tokens.theme.inc',
 | 
			
		||||
    ),
 | 
			
		||||
  );
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  return $theme;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -75,7 +90,14 @@ function addressfield_tokens_field_formatter_info() {
 | 
			
		||||
      'label' => t('Address components'),
 | 
			
		||||
      'field types' => array('addressfield'),
 | 
			
		||||
      'settings' => array(
 | 
			
		||||
        'components' => array('thoroughfare', 'premise', 'locality', 'administrative_area', 'postal_code', 'country'),
 | 
			
		||||
        'components' => array(
 | 
			
		||||
          'thoroughfare',
 | 
			
		||||
          'premise',
 | 
			
		||||
          'locality',
 | 
			
		||||
          'administrative_area',
 | 
			
		||||
          'postal_code',
 | 
			
		||||
          'country',
 | 
			
		||||
        ),
 | 
			
		||||
        'separator' => ', ',
 | 
			
		||||
      ),
 | 
			
		||||
    ),
 | 
			
		||||
@@ -103,14 +125,13 @@ function addressfield_tokens_field_formatter_settings_form($field, $instance, $v
 | 
			
		||||
    $element['separator'] = array(
 | 
			
		||||
      '#type' => 'textfield',
 | 
			
		||||
      '#title' => t('Separator'),
 | 
			
		||||
      '#description' => t('The separator to use between components. Use \n for a line break.'),
 | 
			
		||||
      '#description' => t('The separator to use between components. Use br tag for a line break.'),
 | 
			
		||||
      '#default_value' => $settings['separator'],
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return $element;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_field_formatter_settings_summary().
 | 
			
		||||
 */
 | 
			
		||||
@@ -132,7 +153,7 @@ function addressfield_tokens_field_formatter_settings_summary($field, $instance,
 | 
			
		||||
 */
 | 
			
		||||
function addressfield_tokens_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
 | 
			
		||||
  $element = array();
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  switch ($display['type']) {
 | 
			
		||||
    case 'addressfield_citystate':
 | 
			
		||||
      $theme = array('addressfield_formatter__citystate', 'addressfield_formatter');
 | 
			
		||||
@@ -147,7 +168,7 @@ function addressfield_tokens_field_formatter_view($entity_type, $entity, $field,
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
    case 'addressfield_linear':
 | 
			
		||||
      $theme = array('addressfield_formatter__linear', 'addressfield_formatter');
 | 
			
		||||
 | 
			
		||||
@@ -161,7 +182,7 @@ function addressfield_tokens_field_formatter_view($entity_type, $entity, $field,
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
    case 'addressfield_country':
 | 
			
		||||
      foreach ($items as $delta => $item) {
 | 
			
		||||
        if (!empty($item['country'])) {
 | 
			
		||||
@@ -175,11 +196,11 @@ function addressfield_tokens_field_formatter_view($entity_type, $entity, $field,
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
    case 'addressfield_state':
 | 
			
		||||
      foreach ($items as $delta => $item) {
 | 
			
		||||
        if (!empty($item['country']) && !empty($item['administrative_area'])) {
 | 
			
		||||
          $state = _addressfield_tokens_state($item['country'], $item['administrative_area']);
 | 
			
		||||
          $state = addressfield_tokens_state($item['country'], $item['administrative_area']);
 | 
			
		||||
          $element[$delta] = array(
 | 
			
		||||
            '#type' => 'markup',
 | 
			
		||||
            '#markup' => filter_xss($state),
 | 
			
		||||
@@ -189,19 +210,19 @@ function addressfield_tokens_field_formatter_view($entity_type, $entity, $field,
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
    case 'addressfield_components':
 | 
			
		||||
      $theme = array('addressfield_formatter__components', 'addressfield_formatter');
 | 
			
		||||
      $settings = $display['settings'];
 | 
			
		||||
      foreach ($items as $delta => $item) {
 | 
			
		||||
        if (!empty($item['country'])) {
 | 
			
		||||
          array_unshift($theme, 'addressfield_formatter__components__' . $item['country']);
 | 
			
		||||
        }      
 | 
			
		||||
        }
 | 
			
		||||
        $element[$delta] = array(
 | 
			
		||||
          '#theme' => $theme,
 | 
			
		||||
          '#address' => array_map('filter_xss', $item),
 | 
			
		||||
          '#components' => $settings['components'],
 | 
			
		||||
          '#separator' => filter_xss($settings['separator']),
 | 
			
		||||
          '#separator' => filter_xss($settings['separator'], array('br')),
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
@@ -230,11 +251,31 @@ function addressfield_tokens_property_names() {
 | 
			
		||||
  return $names;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generates token components.
 | 
			
		||||
 *
 | 
			
		||||
 * @return mixed
 | 
			
		||||
 *   Array of components.
 | 
			
		||||
 */
 | 
			
		||||
function addressfield_tokens_components() {
 | 
			
		||||
  $comps = &drupal_static(__FUNCTION__, array());
 | 
			
		||||
  if (empty($comps)) {
 | 
			
		||||
    $names = addressfield_tokens_property_names();
 | 
			
		||||
    foreach (array('first_name', 'last_name', 'name_line', 'organisation_name', 'thoroughfare', 'premise', 'locality', 'dependent_locality', 'administrative_area', 'sub_administrative_area', 'postal_code', 'country') as $key) {
 | 
			
		||||
    $fields = array(
 | 
			
		||||
      'first_name',
 | 
			
		||||
      'last_name',
 | 
			
		||||
      'name_line',
 | 
			
		||||
      'organisation_name',
 | 
			
		||||
      'thoroughfare',
 | 
			
		||||
      'premise',
 | 
			
		||||
      'locality',
 | 
			
		||||
      'dependent_locality',
 | 
			
		||||
      'administrative_area',
 | 
			
		||||
      'sub_administrative_area',
 | 
			
		||||
      'postal_code',
 | 
			
		||||
      'country',
 | 
			
		||||
    );
 | 
			
		||||
    foreach ($fields as $key) {
 | 
			
		||||
      $comps[$key] = $names[$key];
 | 
			
		||||
      if (in_array($key, array('administrative_area', 'country'))) {
 | 
			
		||||
        $comps[$key . '_full'] = t('@name (full)', array(
 | 
			
		||||
@@ -248,14 +289,15 @@ function addressfield_tokens_components() {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets the list of countries from the locale settings in Drupal.
 | 
			
		||||
 * 
 | 
			
		||||
 * @return array An array of countries.  The keys are the 2-letter 
 | 
			
		||||
 *
 | 
			
		||||
 * @return array
 | 
			
		||||
 *   An array of countries. The keys are the 2-letter
 | 
			
		||||
 *   abbreviations and the values are the full country names.
 | 
			
		||||
 */
 | 
			
		||||
function _addressfield_tokens_countries() {
 | 
			
		||||
  $countries = &drupal_static(__FUNCTION__);
 | 
			
		||||
  if (empty($countries)) {
 | 
			
		||||
    include_once('includes/locale.inc');
 | 
			
		||||
    require_once DRUPAL_ROOT . '/includes/locale.inc';
 | 
			
		||||
    $countries = country_get_list();
 | 
			
		||||
  }
 | 
			
		||||
  return $countries;
 | 
			
		||||
@@ -263,14 +305,17 @@ function _addressfield_tokens_countries() {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets the name of the country with the given abbreviation.
 | 
			
		||||
 * 
 | 
			
		||||
 * @param string $country The 2-letter abbreviation of the country.
 | 
			
		||||
 * @return string The name of the country, or FALSE.
 | 
			
		||||
 *
 | 
			
		||||
 * @param string $country
 | 
			
		||||
 *   The 2-letter abbreviation of the country.
 | 
			
		||||
 *
 | 
			
		||||
 * @return string
 | 
			
		||||
 *   The name of the country, or FALSE.
 | 
			
		||||
 */
 | 
			
		||||
function _addressfield_tokens_country($country) {
 | 
			
		||||
  $countries = _addressfield_tokens_countries();
 | 
			
		||||
  
 | 
			
		||||
  // Country abbreviations will always be two uppercase letters. 
 | 
			
		||||
 | 
			
		||||
  // Country abbreviations will always be two uppercase letters.
 | 
			
		||||
  $country = drupal_strtoupper($country);
 | 
			
		||||
  if (!empty($country) && isset($countries[$country])) {
 | 
			
		||||
    return check_plain($countries[$country]);
 | 
			
		||||
@@ -279,11 +324,12 @@ function _addressfield_tokens_country($country) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets the abbreviation of the country with the given name
 | 
			
		||||
 * 
 | 
			
		||||
 * @param string
 | 
			
		||||
 * Gets the abbreviation of the country with the given name.
 | 
			
		||||
 *
 | 
			
		||||
 * @param string $country
 | 
			
		||||
 *   The name of the country.
 | 
			
		||||
 * @return string $country
 | 
			
		||||
 *
 | 
			
		||||
 * @return string
 | 
			
		||||
 *   The 2-letter abbreviation of the country, or FALSE.
 | 
			
		||||
 */
 | 
			
		||||
function _addressfield_tokens_country_abbr($country) {
 | 
			
		||||
@@ -297,55 +343,63 @@ function _addressfield_tokens_country_abbr($country) {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets the list of states in the given country.
 | 
			
		||||
 * 
 | 
			
		||||
 * @param string $country The 2-letter abbreviation of the country.
 | 
			
		||||
 * 
 | 
			
		||||
 * @return array An array of countries.  The keys are the 2-letter 
 | 
			
		||||
 *
 | 
			
		||||
 * @param string $country
 | 
			
		||||
 *   The 2-letter abbreviation of the country.
 | 
			
		||||
 *
 | 
			
		||||
 * @return array
 | 
			
		||||
 *   An array of countries. The keys are the 2-letter
 | 
			
		||||
 *   abbreviations and the values are the full country names.
 | 
			
		||||
 */
 | 
			
		||||
function _addressfield_tokens_states($country) {
 | 
			
		||||
function addressfield_tokens_states($country) {
 | 
			
		||||
  global $language;
 | 
			
		||||
  $langcode = $language->language;
 | 
			
		||||
  $states = &drupal_static(__FUNCTION__);
 | 
			
		||||
  $country = drupal_strtoupper($country);
 | 
			
		||||
  if (!isset($states[$country])) {
 | 
			
		||||
    $cache = cache_get('addressfield_tokens_states');
 | 
			
		||||
    $cache = cache_get('addressfield_tokens_states:' . $langcode);
 | 
			
		||||
    if ($cache) {
 | 
			
		||||
      $states = $cache->data;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (!isset($states[$country])) {
 | 
			
		||||
    $format = addressfield_generate(array('country' => $country), array('address'), array('mode' => 'render'));
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (isset($format['locality_block']['administrative_area']['#options'])) {
 | 
			
		||||
      $states[$country] = $format['locality_block']['administrative_area']['#options'];
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      $states[$country] = array();
 | 
			
		||||
    }
 | 
			
		||||
    cache_set('addressfield_tokens_states', $states);
 | 
			
		||||
    cache_set('addressfield_tokens_states:' . $langcode, $states);
 | 
			
		||||
  }
 | 
			
		||||
  return $states[$country];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets the name of the state with the given abbreviation.
 | 
			
		||||
 * 
 | 
			
		||||
 * @param string $country The 2-letter abbreviation of the country.
 | 
			
		||||
 * @param string $state The 2-letter abbreviation of the state.
 | 
			
		||||
 * @return string The name of the state, or FALSE.
 | 
			
		||||
 *
 | 
			
		||||
 * @param string $country
 | 
			
		||||
 *    The 2-letter abbreviation of the country.
 | 
			
		||||
 * @param string $state
 | 
			
		||||
 *   The 2-letter abbreviation of the state.
 | 
			
		||||
 *
 | 
			
		||||
 * @return string
 | 
			
		||||
 *   The name of the state, or FALSE.
 | 
			
		||||
 */
 | 
			
		||||
function _addressfield_tokens_state($country, $state) {
 | 
			
		||||
  $states = _addressfield_tokens_states($country);
 | 
			
		||||
  
 | 
			
		||||
  // State abbreviations will usually be two uppercase letters. 
 | 
			
		||||
  $state = drupal_strtoupper($state);
 | 
			
		||||
  if (!empty($state) && !empty($states[$state])) {
 | 
			
		||||
function addressfield_tokens_state($country, $state) {
 | 
			
		||||
  $states = addressfield_tokens_states($country);
 | 
			
		||||
 | 
			
		||||
  // State abbreviations will usually be two uppercase letters.
 | 
			
		||||
  $state_upper = drupal_strtoupper($state);
 | 
			
		||||
  if (!empty($state_upper) && !empty($states[$state_upper])) {
 | 
			
		||||
    return check_plain($states[$state]);
 | 
			
		||||
  }
 | 
			
		||||
  return check_plain($state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * Implements hook_webform_component_info(). 
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_webform_component_info().
 | 
			
		||||
 */
 | 
			
		||||
function addressfield_tokens_webform_component_info() {
 | 
			
		||||
  $components = array();
 | 
			
		||||
@@ -387,6 +441,15 @@ function addressfield_tokens_webform_component_info() {
 | 
			
		||||
  return $components;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Retrieves node components based on Node ID.
 | 
			
		||||
 | 
			
		||||
 * @param int $nid
 | 
			
		||||
 *   Node ID.
 | 
			
		||||
 *
 | 
			
		||||
 * @return mixed
 | 
			
		||||
 *   Components.
 | 
			
		||||
 */
 | 
			
		||||
function _addressfield_tokens_webform_components($nid) {
 | 
			
		||||
  $components = &drupal_static(__FUNCTION__, array());
 | 
			
		||||
  if (!isset($components[$nid])) {
 | 
			
		||||
@@ -402,13 +465,14 @@ function _addressfield_tokens_webform_components($nid) {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_webform_submission_load().
 | 
			
		||||
 */
 | 
			
		||||
 * Commented out to solve issue https://www.drupal.org/project/addressfield_tokens/issues/2674752
 | 
			
		||||
 *
 | 
			
		||||
function addressfield_tokens_webform_submission_load(&$submissions) {
 | 
			
		||||
  $submissions_reset = reset($submissions);
 | 
			
		||||
  $nid = $submissions_reset->nid;
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  $components = _addressfield_tokens_webform_components($nid);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
  foreach ($submissions as $sid => $submission) {
 | 
			
		||||
    foreach ($components as $cid => $component) {
 | 
			
		||||
      if (!empty($submission->data[$cid])) {
 | 
			
		||||
@@ -421,17 +485,40 @@ function addressfield_tokens_webform_submission_load(&$submissions) {
 | 
			
		||||
          $data = empty($data) ? array() : unserialize($data);
 | 
			
		||||
          $addresses[$delta] = $data;
 | 
			
		||||
        }
 | 
			
		||||
        drupal_array_set_nested_value($submission->data, $parents, $addresses);
 | 
			
		||||
        if (count($addresses)) {
 | 
			
		||||
          drupal_array_set_nested_value($submission->data, $parents, $addresses);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
**/
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * Implements hook_webform_validator_alter(). 
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_webform_validator_alter().
 | 
			
		||||
 */
 | 
			
		||||
function addressfield_tokens_webform_validator_alter(&$validators) {
 | 
			
		||||
  $validators['unique']['component_types'][] = 'addressfield';
 | 
			
		||||
  $validators['oneoftwo']['component_types'][] = 'addressfield';
 | 
			
		||||
  $validators['oneofseveral']['component_types'][] = 'addressfield';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_webform_hints_element_alter().
 | 
			
		||||
 */
 | 
			
		||||
function addressfield_tokens_webform_hints_element_alter(&$element, &$required_label)
 | 
			
		||||
{
 | 
			
		||||
  if ($element['#type'] == 'addressfield_container' || $element['#type'] == 'fieldset') {
 | 
			
		||||
    $addressfield_tokens_fields_info = addressfield_tokens_field_formatter_info();
 | 
			
		||||
    foreach ($addressfield_tokens_fields_info['addressfield_components']['settings']['components'] as $component) {
 | 
			
		||||
      if (isset($element[$component])) {
 | 
			
		||||
        if (isset($element[$component]['#options'])) {
 | 
			
		||||
          $element[$component]['#empty_option'] = '- ' . $element[$component]['#title'] . $required_label . ' -';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $element[$component]['#attributes']['placeholder'] = $element[$component]['#title'] . $required_label;
 | 
			
		||||
        $element[$component]['#title_display'] = 'invisible';
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,13 @@
 | 
			
		||||
 */
 | 
			
		||||
function theme_addressfield_formatter($vars) {
 | 
			
		||||
  $address = $vars['address'];
 | 
			
		||||
  if (isset($address['addressfield'])) {
 | 
			
		||||
    $address = $address['addressfield'];
 | 
			
		||||
  }
 | 
			
		||||
  $handlers = $vars['handlers'];
 | 
			
		||||
  if (empty($handlers)) {
 | 
			
		||||
    $handlers = array('address');
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  $out = addressfield_generate($address, $handlers, array('mode' => 'render'));
 | 
			
		||||
  return '<div class="addressfield">' . render($out) . '</div>';
 | 
			
		||||
@@ -39,7 +45,7 @@ function theme_addressfield_formatter__citystate($vars) {
 | 
			
		||||
  
 | 
			
		||||
  // If there's no location, render an alternate
 | 
			
		||||
  if (empty($out)) {
 | 
			
		||||
    $out[] = 'Undefined';
 | 
			
		||||
    return '';
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Render the location components
 | 
			
		||||
@@ -56,6 +62,18 @@ function theme_addressfield_formatter__citystate($vars) {
 | 
			
		||||
function theme_addressfield_formatter__linear($vars) {
 | 
			
		||||
  $loc = $vars['address'];
 | 
			
		||||
  
 | 
			
		||||
  // If single line name is empty, construct it from first and last name.
 | 
			
		||||
  if (empty($loc['name_line'])) {
 | 
			
		||||
    $parts = array();
 | 
			
		||||
    if (!empty($loc['first_name'])) {
 | 
			
		||||
      $parts[] = $loc['first_name'];
 | 
			
		||||
    }
 | 
			
		||||
    if (!empty($loc['last_name'])) {
 | 
			
		||||
      $parts[] = $loc['last_name'];
 | 
			
		||||
    }
 | 
			
		||||
    $loc['name_line'] = join(' ', $parts);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Determine which location components to render
 | 
			
		||||
  $out = array();
 | 
			
		||||
  if (!empty($loc['name_line']) && $vars['name_line']) {
 | 
			
		||||
@@ -103,9 +121,9 @@ function theme_addressfield_formatter__components($vars) {
 | 
			
		||||
      $out[$key] = _addressfield_tokens_country($loc['country']);
 | 
			
		||||
    }
 | 
			
		||||
    elseif ($key == 'administrative_area_full' && !empty($loc['country']) && !empty($loc['administrative_area'])) {
 | 
			
		||||
      $out[$key] = _addressfield_tokens_state($loc['country'], $loc['administrative_area']);
 | 
			
		||||
      $out[$key] = addressfield_tokens_state($loc['country'], $loc['administrative_area']);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  return implode($separator, $out);
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,36 +1,37 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file Provides token replacements for address fields.
 | 
			
		||||
*/
 | 
			
		||||
 * @file
 | 
			
		||||
 * Provides token replacements for address fields.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_token_info_alter().
 | 
			
		||||
 * 
 | 
			
		||||
 * Attaches tokens to all addressfield properties.  The default names of each 
 | 
			
		||||
 * addressfield component can be altered by administrators according to the site's locale.
 | 
			
		||||
 * 
 | 
			
		||||
 * @param array $info The existing token info.
 | 
			
		||||
 *
 | 
			
		||||
 * Attaches tokens to all addressfield properties. The default names of each
 | 
			
		||||
 * addressfield component can be altered by administrators according to the
 | 
			
		||||
 * site's locale.
 | 
			
		||||
 */
 | 
			
		||||
function addressfield_tokens_token_info_alter(&$info) {
 | 
			
		||||
  // Define the address field token types 
 | 
			
		||||
  // Define the address field token types.
 | 
			
		||||
  $info['types']['addressfield'] = array(
 | 
			
		||||
    'name' => t('Address field'),
 | 
			
		||||
    'description' => t('An address associated with an entity.'),
 | 
			
		||||
    'needs-data' => 'addressfield',
 | 
			
		||||
  );
 | 
			
		||||
  
 | 
			
		||||
  // Add tokens for each component of the address
 | 
			
		||||
  $info['tokens'] += array( 'addressfield' => array() );
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  // Add tokens for each component of the address.
 | 
			
		||||
  $info['tokens'] += array('addressfield' => array());
 | 
			
		||||
 | 
			
		||||
  $props = addressfield_data_property_info();
 | 
			
		||||
  $names = addressfield_tokens_property_names();
 | 
			
		||||
  $params = array(
 | 
			
		||||
    '@default_country' => addressfield_tokens_default_country(),
 | 
			
		||||
  );
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  foreach ($props as $field => $data) {
 | 
			
		||||
    $fieldtoken = str_replace('_', '-', $field);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (!empty($names[$field])) {
 | 
			
		||||
      $name = $names[$field];
 | 
			
		||||
      $descr = $data['label'];
 | 
			
		||||
@@ -38,7 +39,7 @@ function addressfield_tokens_token_info_alter(&$info) {
 | 
			
		||||
    else {
 | 
			
		||||
      $name = $data['label'];
 | 
			
		||||
      $descr = $name;
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
      $matches = array();
 | 
			
		||||
      if (preg_match('/^(.*)\s+\(i\.e\.\s+(.*)\)$/', $name, $matches)) {
 | 
			
		||||
        $name = $matches[1];
 | 
			
		||||
@@ -54,7 +55,7 @@ function addressfield_tokens_token_info_alter(&$info) {
 | 
			
		||||
  }
 | 
			
		||||
  $info['tokens']['addressfield']['administrative-area']['name'] .= ' (abbreviation)';
 | 
			
		||||
  $info['tokens']['addressfield']['country']['name'] .= ' (abbreviation)';
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  // Add tokens for the formatted address and text-only version.
 | 
			
		||||
  $info['tokens']['addressfield'] += array(
 | 
			
		||||
    'full' => array(
 | 
			
		||||
@@ -83,7 +84,7 @@ function addressfield_tokens_token_info_alter(&$info) {
 | 
			
		||||
      'type' => 'text',
 | 
			
		||||
    ),
 | 
			
		||||
  );
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  // Add user tokens that are useful for MailChimp.
 | 
			
		||||
  if (module_exists('mailchimp')) {
 | 
			
		||||
    $info['tokens']['addressfield'] += array(
 | 
			
		||||
@@ -95,9 +96,23 @@ function addressfield_tokens_token_info_alter(&$info) {
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Attach tokens to all address fields
 | 
			
		||||
  // Add extra text to webform submission values help.
 | 
			
		||||
  if (array_key_exists('submission', $info['tokens'])) {
 | 
			
		||||
    $info['tokens']['submission']['values']['description'] .= '
 | 
			
		||||
      <div>
 | 
			
		||||
      ' . t('For addressfield components you can also choose individual elements of the address using the syntax field_key:element, For example:') . '
 | 
			
		||||
      <ul>
 | 
			
		||||
        <li>[submission:values:address:thoroughfare]</li>
 | 
			
		||||
        <li>[submission:values:address:locality]</li>
 | 
			
		||||
        <li>[submission:values:address:administrative_area]</li>
 | 
			
		||||
        <li>[submission:values:address:postal_code]</li>
 | 
			
		||||
        <li>[submission:values:address:country]</li>
 | 
			
		||||
      </ul>
 | 
			
		||||
    </div>';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Attach tokens to all address fields.
 | 
			
		||||
  $valid_types = entity_token_types();
 | 
			
		||||
  $entity_info = entity_get_info();
 | 
			
		||||
 | 
			
		||||
  foreach ($valid_types as $token_type => $type) {
 | 
			
		||||
    foreach (entity_get_all_property_info($type) as $name => $property) {
 | 
			
		||||
@@ -116,14 +131,6 @@ function addressfield_tokens_token_info_alter(&$info) {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_tokens().
 | 
			
		||||
 * 
 | 
			
		||||
 * @param string $type The type of tokens to replace.  We are looking for 'addressfield', but can also chain 
 | 
			
		||||
 *   addressfields onto entities that have addressfields as properties.
 | 
			
		||||
 * @param array $tokens The tokens to replace.
 | 
			
		||||
 * @param array $data The data to use as replacements.  We are looking for an 'addressfield' property.
 | 
			
		||||
 * @param array $options Additional options for the tokenizer.
 | 
			
		||||
 * 
 | 
			
		||||
 * @return array The replaced values.
 | 
			
		||||
 */
 | 
			
		||||
function addressfield_tokens_tokens($type, $tokens, array $data = array(), array $options = array()) {
 | 
			
		||||
  $url_options = array();
 | 
			
		||||
@@ -140,27 +147,49 @@ function addressfield_tokens_tokens($type, $tokens, array $data = array(), array
 | 
			
		||||
  $replacements = array();
 | 
			
		||||
  $last_original = NULL;
 | 
			
		||||
 | 
			
		||||
  // Process address field tokens
 | 
			
		||||
  if ($type == 'addressfield' && !empty($data['addressfield'])) {
 | 
			
		||||
  // Process webform submission addressfield tokens.
 | 
			
		||||
  if ($type == 'submission' && !empty($data['webform-submission'])) {
 | 
			
		||||
    $submission = $data['webform-submission'];
 | 
			
		||||
    $node = isset($data['node']) ? $data['node'] : node_load($submission->nid);
 | 
			
		||||
    $value_tokens = token_find_with_prefix($tokens, 'values');
 | 
			
		||||
    // Loop through the components of the webform looking for addressfield
 | 
			
		||||
    // components with the expected form_key.
 | 
			
		||||
    foreach ($node->webform['components'] as $cid => $component) {
 | 
			
		||||
      if ($component['type'] == 'addressfield' && isset($submission->data[$cid][0])) {
 | 
			
		||||
        $address = $submission->data[$cid][0];
 | 
			
		||||
        if (is_string($address)) {
 | 
			
		||||
          $address = unserialize($address);
 | 
			
		||||
        }
 | 
			
		||||
        $address_tokens = token_find_with_prefix($value_tokens, $component['form_key']);
 | 
			
		||||
        foreach ($address_tokens as $token => $original) {
 | 
			
		||||
          if (isset($address[$token])) {
 | 
			
		||||
            $replacements[$original] = $sanitize ? filter_xss($address[$token]) : $address[$token];
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // Process address field tokens.
 | 
			
		||||
  elseif ($type == 'addressfield' && !empty($data['addressfield'])) {
 | 
			
		||||
    foreach ($tokens as $name => $original) {
 | 
			
		||||
      $last_original = $original;
 | 
			
		||||
      $name = str_replace('-', '_', $name);
 | 
			
		||||
      $address = $data['addressfield'];
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
      // If the address field exists, use it.
 | 
			
		||||
      if (isset($address[$name])) {
 | 
			
		||||
        $replacements[$original] = $sanitize ? filter_xss($address[$name]) : $address[$name];
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        // Otherwise, it's a special token
 | 
			
		||||
        // Otherwise, it's a special token.
 | 
			
		||||
        switch ($name) {
 | 
			
		||||
          case 'full':
 | 
			
		||||
            $render = addressfield_generate($address, array('address'), array(
 | 
			
		||||
              'mode' => 'render', 
 | 
			
		||||
              'mode' => 'render',
 | 
			
		||||
            ));
 | 
			
		||||
            $replacements[$original] = $sanitize ? filter_xss(drupal_render($render)) : drupal_render($render);
 | 
			
		||||
            break;
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
          case 'text':
 | 
			
		||||
            $out = array();
 | 
			
		||||
            if (!empty($address['thoroughfare'])) {
 | 
			
		||||
@@ -182,7 +211,7 @@ function addressfield_tokens_tokens($type, $tokens, array $data = array(), array
 | 
			
		||||
            }
 | 
			
		||||
            $replacements[$original] = $sanitize ? filter_xss(implode("\n", $out)) : implode("\n", $out);
 | 
			
		||||
            break;
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
          case 'city_state':
 | 
			
		||||
            $out = array();
 | 
			
		||||
            if (!empty($address['locality'])) {
 | 
			
		||||
@@ -194,20 +223,20 @@ function addressfield_tokens_tokens($type, $tokens, array $data = array(), array
 | 
			
		||||
            if (!empty($address['country']) && $address['country'] != addressfield_tokens_default_country()) {
 | 
			
		||||
              $out[] = _addressfield_tokens_country($address['country']);
 | 
			
		||||
            }
 | 
			
		||||
            $replacements[$original] = $sanitize ? filter_xss(implode(", ", $out)) : implode(", ", $out); 
 | 
			
		||||
            $replacements[$original] = $sanitize ? filter_xss(implode(", ", $out)) : implode(", ", $out);
 | 
			
		||||
            break;
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
          case 'state_name':
 | 
			
		||||
            if (!empty($address['administrative_area']) && !empty($address['country'])) {
 | 
			
		||||
              if ($sanitize) {
 | 
			
		||||
                $replacements[$original] = filter_xss(_addressfield_tokens_state($address['country'], $address['administrative_area']));
 | 
			
		||||
                $replacements[$original] = filter_xss(addressfield_tokens_state($address['country'], $address['administrative_area']));
 | 
			
		||||
              }
 | 
			
		||||
              else {
 | 
			
		||||
                $replacements[$original] = _addressfield_tokens_state($address['country'], $address['administrative_area']);
 | 
			
		||||
                $replacements[$original] = addressfield_tokens_state($address['country'], $address['administrative_area']);
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
          case 'country_name':
 | 
			
		||||
            if (!empty($address['country'])) {
 | 
			
		||||
              if ($sanitize) {
 | 
			
		||||
@@ -218,16 +247,23 @@ function addressfield_tokens_tokens($type, $tokens, array $data = array(), array
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
          
 | 
			
		||||
 | 
			
		||||
          case 'mc_address':
 | 
			
		||||
            $address_components = array('thoroughfare', 'premise', 'locality', 'administrative_area', 'postal_code', 'country');
 | 
			
		||||
            $address_components = array(
 | 
			
		||||
              'thoroughfare',
 | 
			
		||||
              'premise',
 | 
			
		||||
              'locality',
 | 
			
		||||
              'administrative_area',
 | 
			
		||||
              'postal_code',
 | 
			
		||||
              'country',
 | 
			
		||||
            );
 | 
			
		||||
            $mc_address = array();
 | 
			
		||||
            foreach ($address_components as $component) {
 | 
			
		||||
              if (!empty($address[$component])) {
 | 
			
		||||
                $mc_address[] = check_plain($address[$component]);
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            // MailChimp requires the address to be a string of double-space 
 | 
			
		||||
            // MailChimp requires the address to be a string of double-space
 | 
			
		||||
            // delimited address fields. (http://kb.mailchimp.com/article/how-do-i-set-up-the-address-field-type-for-import)
 | 
			
		||||
            $replacements[$original] = !empty($mc_address) ? implode('  ', $mc_address) : '';
 | 
			
		||||
            break;
 | 
			
		||||
@@ -242,7 +278,7 @@ function addressfield_tokens_tokens($type, $tokens, array $data = array(), array
 | 
			
		||||
    $token_types = entity_token_types();
 | 
			
		||||
    $info = token_info();
 | 
			
		||||
    if (isset($info['tokens'][$type])) {
 | 
			
		||||
      // Otherwise, chain address fields attached to other entities
 | 
			
		||||
      // Otherwise, chain address fields attached to other entities.
 | 
			
		||||
      foreach ($info['tokens'][$type] as $name => $token_info) {
 | 
			
		||||
        if (isset($token_info['type']) && $token_info['type'] == 'addressfield') {
 | 
			
		||||
          if ($chained_tokens = token_find_with_prefix($tokens, $name)) {
 | 
			
		||||
@@ -261,6 +297,6 @@ function addressfield_tokens_tokens($type, $tokens, array $data = array(), array
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  return $replacements;
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Contains the predefined address formats.
 | 
			
		||||
 *
 | 
			
		||||
 * Derived from Google's dataset: https://i18napis.appspot.com/address.
 | 
			
		||||
 * Derived from Google's dataset: https://chromium-i18n.appspot.com/ssl-address.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -40,12 +40,13 @@ function addressfield_get_address_format($country_code) {
 | 
			
		||||
  // These formats differ from the default only by the presence of the
 | 
			
		||||
  // postal code in 'used_fields'.
 | 
			
		||||
  $countries_with_optional_postal_code = array(
 | 
			
		||||
    'AC', 'AD', 'AL', 'AZ', 'BA', 'BB', 'BD', 'BG', 'BH', 'BM', 'BN', 'BT',
 | 
			
		||||
    'CR', 'CY', 'DO', 'DZ', 'EC', 'EH', 'ET', 'FO', 'GE', 'GN', 'GT',
 | 
			
		||||
    'GW', 'HR', 'HT', 'IL', 'IS', 'JO', 'KE', 'KG', 'KH', 'KW', 'LA',
 | 
			
		||||
    'LA', 'LB', 'LK', 'LR', 'LS',  'MA', 'MC', 'MD', 'ME', 'MG', 'MK', 'MM',
 | 
			
		||||
    'MT', 'MU', 'MV', 'NE', 'NP', 'OM', 'PK', 'PY', 'RO', 'RS', 'SA', 'SI',
 | 
			
		||||
    'SN', 'SZ', 'TA', 'TJ', 'TM', 'TN', 'VA', 'VC', 'VG', 'XK', 'ZM',
 | 
			
		||||
    'AC', 'AD', 'AF', 'AI', 'AL', 'AZ', 'BA', 'BB', 'BD', 'BG', 'BH', 'BM',
 | 
			
		||||
    'BN', 'BT', 'CU', 'CR', 'CY', 'DO', 'DZ', 'EC', 'EH', 'ET', 'FO', 'GE',
 | 
			
		||||
    'GN', 'GT', 'GW', 'HR', 'HM', 'HT', 'IL', 'IS', 'JO', 'KE', 'KG', 'KH',
 | 
			
		||||
    'KP', 'KW', 'LA', 'LB', 'LK', 'LR', 'LS',  'MA', 'MC', 'MD', 'ME', 'MG',
 | 
			
		||||
    'MK', 'MM', 'MT', 'MU', 'MV', 'NE', 'NP', 'OM', 'PK', 'PY', 'RO', 'RS',
 | 
			
		||||
    'SA', 'SD', 'SI', 'SN', 'SZ', 'TA', 'TJ', 'TM', 'TN', 'TZ', 'VA', 'VC',
 | 
			
		||||
    'VG', 'XK', 'ZM',
 | 
			
		||||
  );
 | 
			
		||||
  foreach ($countries_with_optional_postal_code as $code) {
 | 
			
		||||
    $address_formats[$code] = array(
 | 
			
		||||
@@ -71,6 +72,8 @@ function addressfield_get_address_format($country_code) {
 | 
			
		||||
  $address_formats['AE'] = array(
 | 
			
		||||
    'used_fields' => array('administrative_area'),
 | 
			
		||||
    'administrative_area_label' => t('Emirate'),
 | 
			
		||||
    'render_administrative_area_value' => TRUE,
 | 
			
		||||
    'required_fields' => array('administrative_area'),
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['AM'] = array(
 | 
			
		||||
    'used_fields' => array('locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
@@ -114,7 +117,7 @@ function addressfield_get_address_format($country_code) {
 | 
			
		||||
    'used_fields' => array('locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['CL'] = array(
 | 
			
		||||
    'used_fields' => array('dependent_locality', 'locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
    'used_fields' => array('locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
    'administrative_area_label' => t('State', array(), array('context' => 'Territory of a country')),
 | 
			
		||||
    'render_administrative_area_value' => TRUE,
 | 
			
		||||
  );
 | 
			
		||||
@@ -122,9 +125,11 @@ function addressfield_get_address_format($country_code) {
 | 
			
		||||
    'used_fields' => array('dependent_locality', 'locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
    'required_fields' => array('locality', 'administrative_area'),
 | 
			
		||||
    'dependent_locality_label' => t('District'),
 | 
			
		||||
    'render_administrative_area_value' => TRUE,
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['CO'] = array(
 | 
			
		||||
    'used_fields' => array('locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
    'required_fields' => array('locality', 'administrative_area'),
 | 
			
		||||
    'administrative_area_label' => t('Department', array(), array('context' => 'Territory of a country')),
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['CV'] = array(
 | 
			
		||||
@@ -142,6 +147,7 @@ function addressfield_get_address_format($country_code) {
 | 
			
		||||
    'used_fields' => array('locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
    'required_fields' => array('locality', 'postal_code'),
 | 
			
		||||
    'administrative_area_label' => t('County'),
 | 
			
		||||
    'render_administrative_area_value' => TRUE,
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['ES'] = array(
 | 
			
		||||
    'used_fields' => array('locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
@@ -155,7 +161,7 @@ function addressfield_get_address_format($country_code) {
 | 
			
		||||
    'postal_code_label' => t('ZIP code'),
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['GB'] = array(
 | 
			
		||||
    'used_fields' => array('locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
    'used_fields' => array('locality', 'postal_code'),
 | 
			
		||||
    'required_fields' => array('locality', 'postal_code'),
 | 
			
		||||
    'locality_label' => t('Town/City'),
 | 
			
		||||
    'administrative_area_label' => t('County'),
 | 
			
		||||
@@ -165,8 +171,8 @@ function addressfield_get_address_format($country_code) {
 | 
			
		||||
    'used_fields' => array('postal_code'),
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['GU'] = array(
 | 
			
		||||
    'used_fields' => array('locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
    'required_fields' => array('locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
    'used_fields' => array('locality', 'postal_code'),
 | 
			
		||||
    'required_fields' => array('locality', 'postal_code'),
 | 
			
		||||
    'administrative_area_label' => t('State', array(), array('context' => 'Territory of a country')),
 | 
			
		||||
    'postal_code_label' => t('ZIP code'),
 | 
			
		||||
  );
 | 
			
		||||
@@ -182,13 +188,15 @@ function addressfield_get_address_format($country_code) {
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['ID'] = array(
 | 
			
		||||
    'used_fields' => array('locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
    'required_fields' => array('administrative_area'),
 | 
			
		||||
    'locality_label' => t('City/Regency'),
 | 
			
		||||
    'render_administrative_area_value' => TRUE,
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['IE'] = array(
 | 
			
		||||
    'used_fields' => array('locality', 'administrative_area'),
 | 
			
		||||
    'used_fields' => array('dependent_locality', 'locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
    'locality_label' => t('Town/City'),
 | 
			
		||||
    'administrative_area_label' => t('County'),
 | 
			
		||||
    'postal_code_label' => t('Eircode'),
 | 
			
		||||
    'render_administrative_area_value' => TRUE,
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['IN'] = array(
 | 
			
		||||
@@ -293,7 +301,7 @@ function addressfield_get_address_format($country_code) {
 | 
			
		||||
    'used_fields' => array('locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['NG'] = array(
 | 
			
		||||
    'used_fields' => array('locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
    'used_fields' => array('dependent_locality', 'locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
    'administrative_area_label' => t('State', array(), array('context' => 'Territory of a country')),
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['NI'] = array(
 | 
			
		||||
@@ -330,6 +338,7 @@ function addressfield_get_address_format($country_code) {
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['PH'] = array(
 | 
			
		||||
    'used_fields' => array('dependent_locality', 'locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
    'render_administrative_area_value' => TRUE,
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['PR'] = array(
 | 
			
		||||
    'used_fields' => array('locality', 'postal_code'),
 | 
			
		||||
@@ -344,7 +353,7 @@ function addressfield_get_address_format($country_code) {
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['RU'] = array(
 | 
			
		||||
    'used_fields' => array('locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
    'required_fields' => array('locality', 'postal_code'),
 | 
			
		||||
    'required_fields' => array('locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
    'render_administrative_area_value' => TRUE,
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['SC'] = array(
 | 
			
		||||
@@ -389,7 +398,7 @@ function addressfield_get_address_format($country_code) {
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['UA'] = array(
 | 
			
		||||
    'used_fields' => array('locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
    'required_fields' => array('locality', 'postal_code'),
 | 
			
		||||
    'required_fields' => array('locality', 'administrative_area', 'postal_code'),
 | 
			
		||||
    'administrative_area_label' => t('Region', array(), array('context' => 'Territory of a country')),
 | 
			
		||||
  );
 | 
			
		||||
  $address_formats['UM'] = array(
 | 
			
		||||
 
 | 
			
		||||
@@ -132,7 +132,7 @@ function _addressfield_get_administrative_areas_defaults() {
 | 
			
		||||
    'AT' => 'Atacama',
 | 
			
		||||
    'BI' => 'Biobío',
 | 
			
		||||
    'CO' => 'Coquimbo',
 | 
			
		||||
    'LI' => 'Libertador General Bernardo O\'Higgins',
 | 
			
		||||
    'LI' => "Libertador General Bernardo O'Higgins",
 | 
			
		||||
    'LL' => 'Los Lagos',
 | 
			
		||||
    'LR' => 'Los Ríos',
 | 
			
		||||
    'MA' => 'Magallanes y de la Antártica Chilena',
 | 
			
		||||
@@ -449,112 +449,112 @@ function _addressfield_get_administrative_areas_defaults() {
 | 
			
		||||
    'AL' => 'Alessandria',
 | 
			
		||||
    'AN' => 'Ancona',
 | 
			
		||||
    'AO' => 'Aosta',
 | 
			
		||||
    'AP' => 'Ascoli Piceno',
 | 
			
		||||
    'AQ' => "L'Aquila",
 | 
			
		||||
    'AR' => 'Arezzo',
 | 
			
		||||
    'AP' => 'Ascoli Piceno',
 | 
			
		||||
    'AT' => 'Asti',
 | 
			
		||||
    'AV' => 'Avellino',
 | 
			
		||||
    'BA' => 'Bari',
 | 
			
		||||
    'BG' => 'Bergamo',
 | 
			
		||||
    'BI' => 'Biella',
 | 
			
		||||
    'BT' => 'Barletta-Andria-Trani',
 | 
			
		||||
    'BL' => 'Belluno',
 | 
			
		||||
    'BN' => 'Benevento',
 | 
			
		||||
    'BG' => 'Bergamo',
 | 
			
		||||
    'BI' => 'Biella',
 | 
			
		||||
    'BO' => 'Bologna',
 | 
			
		||||
    'BR' => 'Brindisi',
 | 
			
		||||
    'BS' => 'Brescia',
 | 
			
		||||
    'BT' => 'Barletta-Andria-Trani',
 | 
			
		||||
    'BZ' => 'Bolzano/Bozen',
 | 
			
		||||
    'BS' => 'Brescia',
 | 
			
		||||
    'BR' => 'Brindisi',
 | 
			
		||||
    'CA' => 'Cagliari',
 | 
			
		||||
    'CB' => 'Campobasso',
 | 
			
		||||
    'CE' => 'Caserta',
 | 
			
		||||
    'CH' => 'Chieti',
 | 
			
		||||
    'CI' => 'Carbonia-Iglesias',
 | 
			
		||||
    'CL' => 'Caltanissetta',
 | 
			
		||||
    'CN' => 'Cuneo',
 | 
			
		||||
    'CO' => 'Como',
 | 
			
		||||
    'CR' => 'Cremona',
 | 
			
		||||
    'CS' => 'Cosenza',
 | 
			
		||||
    'CB' => 'Campobasso',
 | 
			
		||||
    'CI' => 'Carbonia-Iglesias',
 | 
			
		||||
    'CE' => 'Caserta',
 | 
			
		||||
    'CT' => 'Catania',
 | 
			
		||||
    'CZ' => 'Catanzaro',
 | 
			
		||||
    'CH' => 'Chieti',
 | 
			
		||||
    'CO' => 'Como',
 | 
			
		||||
    'CS' => 'Cosenza',
 | 
			
		||||
    'CR' => 'Cremona',
 | 
			
		||||
    'KR' => 'Crotone',
 | 
			
		||||
    'CN' => 'Cuneo',
 | 
			
		||||
    'EN' => 'Enna',
 | 
			
		||||
    'FC' => 'Forlì-Cesena',
 | 
			
		||||
    'FE' => 'Ferrara',
 | 
			
		||||
    'FG' => 'Foggia',
 | 
			
		||||
    'FI' => 'Firenze',
 | 
			
		||||
    'FM' => 'Fermo',
 | 
			
		||||
    'FE' => 'Ferrara',
 | 
			
		||||
    'FI' => 'Firenze',
 | 
			
		||||
    'FG' => 'Foggia',
 | 
			
		||||
    'FC' => 'Forlì-Cesena',
 | 
			
		||||
    'FR' => 'Frosinone',
 | 
			
		||||
    'GE' => 'Genova',
 | 
			
		||||
    'GO' => 'Gorizia',
 | 
			
		||||
    'GR' => 'Grosseto',
 | 
			
		||||
    'IM' => 'Imperia',
 | 
			
		||||
    'IS' => 'Isernia',
 | 
			
		||||
    'KR' => 'Crotone',
 | 
			
		||||
    'LC' => 'Lecco',
 | 
			
		||||
    'AQ' => "L'Aquila",
 | 
			
		||||
    'SP' => 'La Spezia',
 | 
			
		||||
    'LT' => 'Latina',
 | 
			
		||||
    'LE' => 'Lecce',
 | 
			
		||||
    'LC' => 'Lecco',
 | 
			
		||||
    'LI' => 'Livorno',
 | 
			
		||||
    'LO' => 'Lodi',
 | 
			
		||||
    'LT' => 'Latina',
 | 
			
		||||
    'LU' => 'Lucca',
 | 
			
		||||
    'MB' => 'Monza e Brianza',
 | 
			
		||||
    'MC' => 'Macerata',
 | 
			
		||||
    'ME' => 'Messina',
 | 
			
		||||
    'MI' => 'Milano',
 | 
			
		||||
    'MN' => 'Mantova',
 | 
			
		||||
    'MO' => 'Modena',
 | 
			
		||||
    'MS' => 'Massa-Carrara',
 | 
			
		||||
    'MT' => 'Matera',
 | 
			
		||||
    'VS' => 'Medio Campidano',
 | 
			
		||||
    'ME' => 'Messina',
 | 
			
		||||
    'MI' => 'Milano',
 | 
			
		||||
    'MO' => 'Modena',
 | 
			
		||||
    'MB' => 'Monza e Brianza',
 | 
			
		||||
    'NA' => 'Napoli',
 | 
			
		||||
    'NO' => 'Novara',
 | 
			
		||||
    'NU' => 'Nuoro',
 | 
			
		||||
    'OG' => 'Ogliastra',
 | 
			
		||||
    'OR' => 'Oristano',
 | 
			
		||||
    'OT' => 'Olbia-Tempio',
 | 
			
		||||
    'PA' => 'Palermo',
 | 
			
		||||
    'PC' => 'Piacenza',
 | 
			
		||||
    'OR' => 'Oristano',
 | 
			
		||||
    'PD' => 'Padova',
 | 
			
		||||
    'PE' => 'Pescara',
 | 
			
		||||
    'PG' => 'Perugia',
 | 
			
		||||
    'PI' => 'Pisa',
 | 
			
		||||
    'PN' => 'Pordenone',
 | 
			
		||||
    'PO' => 'Prato',
 | 
			
		||||
    'PA' => 'Palermo',
 | 
			
		||||
    'PR' => 'Parma',
 | 
			
		||||
    'PT' => 'Pistoia',
 | 
			
		||||
    'PU' => 'Pesaro e Urbino',
 | 
			
		||||
    'PV' => 'Pavia',
 | 
			
		||||
    'PG' => 'Perugia',
 | 
			
		||||
    'PU' => 'Pesaro e Urbino',
 | 
			
		||||
    'PE' => 'Pescara',
 | 
			
		||||
    'PC' => 'Piacenza',
 | 
			
		||||
    'PI' => 'Pisa',
 | 
			
		||||
    'PT' => 'Pistoia',
 | 
			
		||||
    'PN' => 'Pordenone',
 | 
			
		||||
    'PZ' => 'Potenza',
 | 
			
		||||
    'PO' => 'Prato',
 | 
			
		||||
    'RG' => 'Ragusa',
 | 
			
		||||
    'RA' => 'Ravenna',
 | 
			
		||||
    'RC' => 'Reggio Calabria',
 | 
			
		||||
    'RE' => 'Reggio Emilia',
 | 
			
		||||
    'RG' => 'Ragusa',
 | 
			
		||||
    'RI' => 'Rieti',
 | 
			
		||||
    'RM' => 'Roma',
 | 
			
		||||
    'RN' => 'Rimini',
 | 
			
		||||
    'RM' => 'Roma',
 | 
			
		||||
    'RO' => 'Rovigo',
 | 
			
		||||
    'SA' => 'Salerno',
 | 
			
		||||
    'SI' => 'Siena',
 | 
			
		||||
    'SO' => 'Sondrio',
 | 
			
		||||
    'SP' => 'La Spezia',
 | 
			
		||||
    'SR' => 'Siracusa',
 | 
			
		||||
    'SS' => 'Sassari',
 | 
			
		||||
    'SV' => 'Savona',
 | 
			
		||||
    'SI' => 'Siena',
 | 
			
		||||
    'SR' => 'Siracusa',
 | 
			
		||||
    'SO' => 'Sondrio',
 | 
			
		||||
    'TA' => 'Taranto',
 | 
			
		||||
    'TE' => 'Teramo',
 | 
			
		||||
    'TN' => 'Trento',
 | 
			
		||||
    'TR' => 'Terni',
 | 
			
		||||
    'TO' => 'Torino',
 | 
			
		||||
    'TP' => 'Trapani',
 | 
			
		||||
    'TR' => 'Terni',
 | 
			
		||||
    'TS' => 'Trieste',
 | 
			
		||||
    'TN' => 'Trento',
 | 
			
		||||
    'TV' => 'Treviso',
 | 
			
		||||
    'TS' => 'Trieste',
 | 
			
		||||
    'UD' => 'Udine',
 | 
			
		||||
    'VA' => 'Varese',
 | 
			
		||||
    'VE' => 'Venezia',
 | 
			
		||||
    'VB' => 'Verbano-Cusio-Ossola',
 | 
			
		||||
    'VC' => 'Vercelli',
 | 
			
		||||
    'VE' => 'Venezia',
 | 
			
		||||
    'VI' => 'Vicenza',
 | 
			
		||||
    'VR' => 'Verona',
 | 
			
		||||
    'VS' => 'Medio Campidano',
 | 
			
		||||
    'VT' => 'Viterbo',
 | 
			
		||||
    'VV' => 'Vibo Valentia',
 | 
			
		||||
    'VI' => 'Vicenza',
 | 
			
		||||
    'VT' => 'Viterbo',
 | 
			
		||||
  );
 | 
			
		||||
  $administrative_areas['JM'] = array(
 | 
			
		||||
    '13' => 'Clarendon',
 | 
			
		||||
@@ -663,11 +663,11 @@ function _addressfield_get_administrative_areas_defaults() {
 | 
			
		||||
    'BCN' => 'Baja California',
 | 
			
		||||
    'BCS' => 'Baja California Sur',
 | 
			
		||||
    'CAM' => 'Campeche',
 | 
			
		||||
    'CMX' => 'Ciudad de México',
 | 
			
		||||
    'COA' => 'Coahuila',
 | 
			
		||||
    'COL' => 'Colima',
 | 
			
		||||
    'CHP' => 'Chiapas',
 | 
			
		||||
    'CHH' => 'Chihuahua',
 | 
			
		||||
    'DIF' => 'Distrito Federal',
 | 
			
		||||
    'DUG' => 'Durango',
 | 
			
		||||
    'MEX' => 'Estado de México',
 | 
			
		||||
    'GUA' => 'Guanajuato',
 | 
			
		||||
@@ -709,7 +709,7 @@ function _addressfield_get_administrative_areas_defaults() {
 | 
			
		||||
    '13' => t('Sarawak'),
 | 
			
		||||
    '10' => t('Selangor'),
 | 
			
		||||
    '11' => t('Terengganu'),
 | 
			
		||||
    );
 | 
			
		||||
  );
 | 
			
		||||
  $administrative_areas['PE'] = array(
 | 
			
		||||
    'AMA' => 'Amazonas',
 | 
			
		||||
    'ANC' => 'Ancash',
 | 
			
		||||
@@ -737,6 +737,90 @@ function _addressfield_get_administrative_areas_defaults() {
 | 
			
		||||
    'TUM' => 'Tumbes',
 | 
			
		||||
    'UCA' => 'Ucayali',
 | 
			
		||||
  );
 | 
			
		||||
  $administrative_areas['PH'] = array(
 | 
			
		||||
    'ABR' => 'Abra',
 | 
			
		||||
    'AGN' => 'Agusan del Norte',
 | 
			
		||||
    'AGS' => 'Agusan del Sur',
 | 
			
		||||
    'AKL' => 'Aklan',
 | 
			
		||||
    'ALB' => 'Albay',
 | 
			
		||||
    'ANT' => 'Antique',
 | 
			
		||||
    'APA' => 'Apayao',
 | 
			
		||||
    'AUR' => 'Aurora',
 | 
			
		||||
    'BAS' => 'Basilan',
 | 
			
		||||
    'BAN' => 'Bataan',
 | 
			
		||||
    'BTN' => 'Batanes',
 | 
			
		||||
    'BTG' => 'Batangas',
 | 
			
		||||
    'BEN' => 'Benguet',
 | 
			
		||||
    'BIL' => 'Biliran',
 | 
			
		||||
    'BOH' => 'Bohol',
 | 
			
		||||
    'BUK' => 'Bukidnon',
 | 
			
		||||
    'BUL' => 'Bulacan',
 | 
			
		||||
    'CAG' => 'Cagayan',
 | 
			
		||||
    'CAN' => 'Camarines Norte',
 | 
			
		||||
    'CAS' => 'Camarines Sur',
 | 
			
		||||
    'CAM' => 'Camiguin',
 | 
			
		||||
    'CAP' => 'Capiz',
 | 
			
		||||
    'CAT' => 'Catanduanes',
 | 
			
		||||
    'CAV' => 'Cavite',
 | 
			
		||||
    'CEB' => 'Cebu',
 | 
			
		||||
    'COM' => 'Compostela Valley',
 | 
			
		||||
    'NCO' => 'Cotabato',
 | 
			
		||||
    'DAV' => 'Davao del Norte',
 | 
			
		||||
    'DAS' => 'Davao del Sur',
 | 
			
		||||
    'a9d' => 'Davao Occidental',
 | 
			
		||||
    'DAO' => 'Davao Oriental',
 | 
			
		||||
    'DIN' => 'Dinagat Islands',
 | 
			
		||||
    'EAS' => 'Eastern Samar',
 | 
			
		||||
    'GUI' => 'Guimaras',
 | 
			
		||||
    'IFU' => 'Ifugao',
 | 
			
		||||
    'ILN' => 'Ilocos Norte',
 | 
			
		||||
    'ILS' => 'Ilocos Sur',
 | 
			
		||||
    'ILI' => 'Iloilo',
 | 
			
		||||
    'ISA' => 'Isabela',
 | 
			
		||||
    'KAL' => 'Kalinga',
 | 
			
		||||
    'LUN' => 'La Union',
 | 
			
		||||
    'LAG' => 'Laguna',
 | 
			
		||||
    'LAN' => 'Lanao del Norte',
 | 
			
		||||
    'LAS' => 'Lanao del Sur',
 | 
			
		||||
    'LEY' => 'Leyte',
 | 
			
		||||
    'MAG' => 'Maguindanao',
 | 
			
		||||
    'MAD' => 'Marinduque',
 | 
			
		||||
    'MAS' => 'Masbate',
 | 
			
		||||
    '00' => 'Metro Manila',
 | 
			
		||||
    'MDC' => 'Mindoro Occidental',
 | 
			
		||||
    'MDR' => 'Mindoro Oriental',
 | 
			
		||||
    'MSC' => 'Misamis Occidental',
 | 
			
		||||
    'MSR' => 'Misamis Oriental',
 | 
			
		||||
    'MOU' => 'Mountain Province',
 | 
			
		||||
    'NEC' => 'Negros Occidental',
 | 
			
		||||
    'NER' => 'Negros Oriental',
 | 
			
		||||
    'NSA' => 'Northern Samar',
 | 
			
		||||
    'NUE' => 'Nueva Ecija',
 | 
			
		||||
    'NUV' => 'Nueva Vizcaya',
 | 
			
		||||
    'PLW' => 'Palawan',
 | 
			
		||||
    'PAM' => 'Pampanga',
 | 
			
		||||
    'PAN' => 'Pangasinan',
 | 
			
		||||
    'QUE' => 'Quezon Province',
 | 
			
		||||
    'QUI' => 'Quirino',
 | 
			
		||||
    'RIZ' => 'Rizal',
 | 
			
		||||
    'ROM' => 'Romblon',
 | 
			
		||||
    'WSA' => 'Samar',
 | 
			
		||||
    'SAR' => 'Sarangani',
 | 
			
		||||
    'SIG' => 'Siquijor',
 | 
			
		||||
    'SOR' => 'Sorsogon',
 | 
			
		||||
    'SCO' => 'South Cotabato',
 | 
			
		||||
    'SLE' => 'Southern Leyte',
 | 
			
		||||
    'SUK' => 'Sultan Kudarat',
 | 
			
		||||
    'SLU' => 'Sulu',
 | 
			
		||||
    'SUN' => 'Surigao del Norte',
 | 
			
		||||
    'SUR' => 'Surigao del Sur',
 | 
			
		||||
    'TAR' => 'Tarlac',
 | 
			
		||||
    'TAW' => 'Tawi-Tawi',
 | 
			
		||||
    'ZMB' => 'Zambales',
 | 
			
		||||
    'ZAN' => 'Zamboanga del Norte',
 | 
			
		||||
    'ZAS' => 'Zamboanga del Sur',
 | 
			
		||||
    'ZSI' => 'Zamboanga Sibuguey',
 | 
			
		||||
  );
 | 
			
		||||
  $administrative_areas['RU'] = array(
 | 
			
		||||
    'MOW' => t('Moskva'),
 | 
			
		||||
    'SPE' => t('Sankt-Peterburg'),
 | 
			
		||||
@@ -931,31 +1015,31 @@ function _addressfield_get_administrative_areas_defaults() {
 | 
			
		||||
  );
 | 
			
		||||
  $administrative_areas['UA'] = array(
 | 
			
		||||
    '43' => t('Crimea'),
 | 
			
		||||
    '05' => t('Vinnyts\'ka oblast'),
 | 
			
		||||
    '07' => t('Volyns\'ka oblast'),
 | 
			
		||||
    '05' => t("Vinnyts'ka oblast"),
 | 
			
		||||
    '07' => t("Volyns'ka oblast"),
 | 
			
		||||
    '12' => t('Dnipropetrovsk Oblast'),
 | 
			
		||||
    '14' => t('Donetsk Oblast'),
 | 
			
		||||
    '18' => t('Zhytomyrs\'ka oblast'),
 | 
			
		||||
    '21' => t('Zakarpats\'ka oblast'),
 | 
			
		||||
    '23' => t('Zaporiz\'ka oblast'),
 | 
			
		||||
    '26' => t('Ivano-Frankivs\'ka oblast'),
 | 
			
		||||
    '30' => t('Kiev Oblast'),
 | 
			
		||||
    '35' => t('Kirovohrads\'ka oblast'),
 | 
			
		||||
    '09' => t('Luhans\'ka oblast'),
 | 
			
		||||
    '18' => t("Zhytomyrs'ka oblast"),
 | 
			
		||||
    '21' => t("Zakarpats'ka oblast"),
 | 
			
		||||
    '23' => t("Zaporiz'ka oblast"),
 | 
			
		||||
    '26' => t("Ivano-Frankivs'ka oblast"),
 | 
			
		||||
    '30' => t('Kyiv Oblast'),
 | 
			
		||||
    '35' => t("Kirovohrads'ka oblast"),
 | 
			
		||||
    '09' => t("Luhans'ka oblast"),
 | 
			
		||||
    '46' => t('Lviv Oblast'),
 | 
			
		||||
    '48' => t('Mykolaivs\'ka oblast'),
 | 
			
		||||
    '48' => t("Mykolaivs'ka oblast"),
 | 
			
		||||
    '51' => t('Odessa Oblast'),
 | 
			
		||||
    '53' => t('Poltavs\'ka oblast'),
 | 
			
		||||
    '56' => t('Rivnens\'ka oblast'),
 | 
			
		||||
    '40' => t('Sevastopol\' city'),
 | 
			
		||||
    '59' => t('Sums\'ka oblast'),
 | 
			
		||||
    '61' => t('Ternopil\'s\'ka oblast'),
 | 
			
		||||
    '53' => t("Poltavs'ka oblast"),
 | 
			
		||||
    '56' => t("Rivnens'ka oblast"),
 | 
			
		||||
    '40' => t("Sevastopol' city"),
 | 
			
		||||
    '59' => t("Sums'ka oblast"),
 | 
			
		||||
    '61' => t("Ternopil's'ka oblast"),
 | 
			
		||||
    '63' => t('Kharkiv Oblast'),
 | 
			
		||||
    '65' => t('Khersons\'ka oblast'),
 | 
			
		||||
    '68' => t('Khmel\'nyts\'ka oblast'),
 | 
			
		||||
    '71' => t('Cherkas\'ka oblast'),
 | 
			
		||||
    '77' => t('Chernivets\'ka oblast'),
 | 
			
		||||
    '74' => t('Chernihivs\'ka oblast'),
 | 
			
		||||
    '65' => t("Khersons'ka oblast"),
 | 
			
		||||
    '68' => t("Khmel'nyts'ka oblast"),
 | 
			
		||||
    '71' => t("Cherkas'ka oblast"),
 | 
			
		||||
    '77' => t("Chernivets'ka oblast"),
 | 
			
		||||
    '74' => t("Chernihivs'ka oblast"),
 | 
			
		||||
  );
 | 
			
		||||
  $administrative_areas['US'] = array(
 | 
			
		||||
    'AL' => t('Alabama'),
 | 
			
		||||
 
 | 
			
		||||
@@ -41,9 +41,9 @@ function _addressfield_sample_addresses() {
 | 
			
		||||
  if (!isset($fields)) {
 | 
			
		||||
    $filepath = DRUPAL_ROOT . '/' . drupal_get_path('module', 'addressfield');
 | 
			
		||||
    $fields = array();
 | 
			
		||||
    if ($handle = @fopen("$filepath/addresses.txt",'r')) {
 | 
			
		||||
    if ($handle = @fopen("$filepath/addresses.txt", 'r')) {
 | 
			
		||||
      if (is_resource($handle)) {
 | 
			
		||||
        while (($buffer = fgets($handle)) !== false) {
 | 
			
		||||
        while (($buffer = fgets($handle)) !== FALSE) {
 | 
			
		||||
          list($country, $administrative_area, $sub_administrative_area, $locality, $dependent_locality, $postal_code, $thoroughfare, $premise, $sub_premise) = explode("\t", $buffer);
 | 
			
		||||
          $fields[] = array(
 | 
			
		||||
            'country' => ($country == 'NULL') ? NULL : trim($country),
 | 
			
		||||
 
 | 
			
		||||
@@ -36,10 +36,20 @@ function addressfield_feeds_processor_targets_alter(&$targets, $entity_type, $bu
 | 
			
		||||
 *   A string identifying the target on the node.
 | 
			
		||||
 * @param $values
 | 
			
		||||
 *   The value to populate the target with.
 | 
			
		||||
 * @param array $mapping
 | 
			
		||||
 *  Associative array of the mapping settings from the per mapping
 | 
			
		||||
 *  configuration form.
 | 
			
		||||
 */
 | 
			
		||||
function addressfield_set_target($source, $entity, $target, $values) {
 | 
			
		||||
function addressfield_set_target($source, $entity, $target, $values, $mapping) {
 | 
			
		||||
  $language = $mapping['language'];
 | 
			
		||||
  list($field_name, $sub_field) = explode(':', $target, 2);
 | 
			
		||||
 | 
			
		||||
  // Field info and instance are required for setting default values.
 | 
			
		||||
  $entity_type = $source->importer->processor->entityType();
 | 
			
		||||
  list(, , $bundle_name) = entity_extract_ids($entity_type, $entity);
 | 
			
		||||
  $info = field_info_field($field_name);
 | 
			
		||||
  $instance = field_info_instance($entity_type, $field_name, $bundle_name);
 | 
			
		||||
 | 
			
		||||
  // Convert the values into an array if it isn't one already to correspond to
 | 
			
		||||
  // Drupal's handling of field value arrays.
 | 
			
		||||
  if (!is_array($values)) {
 | 
			
		||||
@@ -48,12 +58,16 @@ function addressfield_set_target($source, $entity, $target, $values) {
 | 
			
		||||
 | 
			
		||||
  // If the field is already set on the given entity, update the existing value
 | 
			
		||||
  // array. Otherwise start with a fresh field value array.
 | 
			
		||||
  $field = isset($entity->$field_name) ? $entity->$field_name : array();
 | 
			
		||||
  $field = isset($entity->{$field_name}) ? $entity->{$field_name} : array();
 | 
			
		||||
 | 
			
		||||
  // Loop over the field values array...
 | 
			
		||||
  foreach ($values as $delta => $value) {
 | 
			
		||||
    $field[LANGUAGE_NONE][$delta][$sub_field] = $value;
 | 
			
		||||
    // Set defaults for new values.
 | 
			
		||||
    if (!isset($field[$language][$delta])) {
 | 
			
		||||
      $field[$language][$delta] = addressfield_default_values($info, $instance);
 | 
			
		||||
    }
 | 
			
		||||
    $field[$language][$delta][$sub_field] = $value;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  $entity->$field_name = $field;
 | 
			
		||||
  $entity->{$field_name} = $field;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,9 +10,8 @@ files[] = views/addressfield_views_handler_field_administrative_area.inc
 | 
			
		||||
files[] = views/addressfield_views_handler_field_country.inc
 | 
			
		||||
files[] = views/addressfield_views_handler_filter_country.inc
 | 
			
		||||
 | 
			
		||||
; Information added by Drupal.org packaging script on 2015-10-07
 | 
			
		||||
version = "7.x-1.2"
 | 
			
		||||
; Information added by Drupal.org packaging script on 2018-10-26
 | 
			
		||||
version = "7.x-1.3"
 | 
			
		||||
core = "7.x"
 | 
			
		||||
project = "addressfield"
 | 
			
		||||
datestamp = "1444254070"
 | 
			
		||||
 | 
			
		||||
datestamp = "1540579391"
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,11 @@
 | 
			
		||||
 * Base integration with the Migrate API class.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// Avoid issues when migrate module is disabled.
 | 
			
		||||
if (!class_exists('MigrateFieldHandler')) {
 | 
			
		||||
  return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_migrate_api().
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
@@ -52,6 +52,37 @@ function addressfield_module_implements_alter(&$implementations, $hook) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns a list of address fields optionally filtered by entity type.
 | 
			
		||||
 *
 | 
			
		||||
 * @param string $entity_type
 | 
			
		||||
 *   Optional machine-name of an entity type to filter the returned array by.
 | 
			
		||||
 *
 | 
			
		||||
 * @return array
 | 
			
		||||
 *   An array of address field mapping data.
 | 
			
		||||
 */
 | 
			
		||||
function addressfield_get_address_fields($entity_type = '') {
 | 
			
		||||
  $fields = &drupal_static(__FUNCTION__ . '_' . $entity_type);
 | 
			
		||||
 | 
			
		||||
  if (isset($fields)) {
 | 
			
		||||
    return $fields;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Get mapping data for all address fields.
 | 
			
		||||
  $fields = array_filter(field_info_field_map(), 'addressfield_field_map_filter');
 | 
			
		||||
 | 
			
		||||
  // Filter the list of fields by entity type if specified.
 | 
			
		||||
  if (!empty($fields) && !empty($entity_type)) {
 | 
			
		||||
    foreach ($fields as $field_name => $field) {
 | 
			
		||||
      if (!isset($field['bundles'][$entity_type])) {
 | 
			
		||||
        unset($fields[$field_name]);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return $fields;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns TRUE if a field map array value represents an addressfield.
 | 
			
		||||
 *
 | 
			
		||||
@@ -305,7 +336,14 @@ function theme_addressfield_container($variables) {
 | 
			
		||||
  if (strlen($element['#children']) > 0) {
 | 
			
		||||
    $output = '<' . $element['#tag'] . drupal_attributes($element['#attributes']) . '>';
 | 
			
		||||
    $output .= $element['#children'];
 | 
			
		||||
    $output .= '</' . $element['#tag'] . ">";
 | 
			
		||||
    $output .= '</' . $element['#tag'] . '>';
 | 
			
		||||
    // Add a linebreak to the HTML after a div. This is invisible on the
 | 
			
		||||
    // rendered page but improves the appearance of address field output when
 | 
			
		||||
    // HTML tags are stripped, such as by Views Data Export.
 | 
			
		||||
    if ($element['#tag'] == 'div') {
 | 
			
		||||
      $output .= PHP_EOL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $output;
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
@@ -446,7 +484,7 @@ function addressfield_field_presave($entity_type, $entity, $field, $instance, $l
 | 
			
		||||
    // spaces to single spaces.
 | 
			
		||||
    foreach ($item as $key => &$value) {
 | 
			
		||||
      if (!in_array($key, array('data')) && is_string($value)) {
 | 
			
		||||
        $value = trim(str_replace('  ', ' ', $value));
 | 
			
		||||
        $value = trim(preg_replace('/[[:blank:]]{2,}/u', ' ', $value));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -89,11 +89,13 @@ function addressfield_token_info() {
 | 
			
		||||
 */
 | 
			
		||||
function addressfield_token_info_alter(&$data) {
 | 
			
		||||
  // Loop over every address field on the site.
 | 
			
		||||
  foreach (array_filter(field_info_field_map(), 'addressfield_field_map_filter') as $field_name => $field) {
 | 
			
		||||
    foreach ($data['tokens'] as $group => $token){
 | 
			
		||||
      if (isset($data['tokens'][$group][$field_name]) && is_array($data['tokens'][$group][$field_name])) {
 | 
			
		||||
        // Set the token type for the field to use the addressfield child tokens.
 | 
			
		||||
        $data['tokens'][$group][$field_name]['type'] = 'address-field';
 | 
			
		||||
  foreach (addressfield_get_address_fields() as $field_name => $field) {
 | 
			
		||||
    foreach (array($field_name, strtr($field_name, '_', '-')) as $name) {
 | 
			
		||||
      foreach ($data['tokens'] as $group => $token) {
 | 
			
		||||
        if (isset($data['tokens'][$group][$name]) && is_array($data['tokens'][$group][$name])) {
 | 
			
		||||
          // Set the token type for the field to use the addressfield child tokens.
 | 
			
		||||
          $data['tokens'][$group][$name]['type'] = 'address-field';
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@@ -212,19 +214,27 @@ function addressfield_tokens($type, $tokens, array $data = array(), array $optio
 | 
			
		||||
  // and helps us avoid having to do the entity detection ourselves.
 | 
			
		||||
  if ($type == 'entity') {
 | 
			
		||||
    // Loop over the address fields defined on the site.
 | 
			
		||||
    foreach (array_filter(field_info_field_map(), 'addressfield_field_map_filter') as $field_name => $field) {
 | 
			
		||||
      // If there are any address field tokens in the token list...
 | 
			
		||||
      if ($addressfield_tokens = token_find_with_prefix($tokens, $field_name)) {
 | 
			
		||||
        // If the current field is on the matching entity type...
 | 
			
		||||
        if (!empty($field['bundles'][$data['entity_type']])) {
 | 
			
		||||
          // Extract the format handlers selected in a representative instance
 | 
			
		||||
          // settings form for use in formatting tokens.
 | 
			
		||||
          $instance = field_info_instance($data['entity_type'], $field_name, reset($field['bundles'][$data['entity_type']]));
 | 
			
		||||
          $format_handlers = $instance['widget']['settings']['format_handlers'];
 | 
			
		||||
    foreach (addressfield_get_address_fields($data['entity_type']) as $field_name => $field) {
 | 
			
		||||
      // If the current field is on the matching entity type...
 | 
			
		||||
      if (!empty($field['bundles'][$data['entity_type']])) {
 | 
			
		||||
        // Extract the format handlers selected in a representative instance
 | 
			
		||||
        // settings form for use in formatting tokens.
 | 
			
		||||
        $instance = field_info_instance($data['entity_type'], $field_name, reset($field['bundles'][$data['entity_type']]));
 | 
			
		||||
        $format_handlers = $instance['widget']['settings']['format_handlers'];
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      foreach (array($field_name, strtr($field_name, '_', '-')) as $prefix) {
 | 
			
		||||
        // If there are any address field tokens in the token list...
 | 
			
		||||
        $addressfield_tokens = token_find_with_prefix($tokens, $prefix);
 | 
			
		||||
 | 
			
		||||
        if (!$addressfield_tokens) {
 | 
			
		||||
          continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Generate the necessary address field tokens for the entity.
 | 
			
		||||
        $replacements += token_generate('address-field', $addressfield_tokens, array('address-field' => $data['entity']->$field_name, 'format_handlers' => $format_handlers), $options);
 | 
			
		||||
        if (property_exists($data['entity'], $field_name)) {
 | 
			
		||||
          // Generate the necessary address field tokens for the entity.
 | 
			
		||||
          $replacements += token_generate('address-field', $addressfield_tokens, array('address-field' => $data['entity']->$field_name, 'format_handlers' => $format_handlers), $options);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -7,9 +7,8 @@ hidden = TRUE
 | 
			
		||||
dependencies[] = ctools
 | 
			
		||||
dependencies[] = addressfield
 | 
			
		||||
 | 
			
		||||
; Information added by Drupal.org packaging script on 2015-10-07
 | 
			
		||||
version = "7.x-1.2"
 | 
			
		||||
; Information added by Drupal.org packaging script on 2018-10-26
 | 
			
		||||
version = "7.x-1.3"
 | 
			
		||||
core = "7.x"
 | 
			
		||||
project = "addressfield"
 | 
			
		||||
datestamp = "1444254070"
 | 
			
		||||
 | 
			
		||||
datestamp = "1540579391"
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,24 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Hide the administrative area field.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
$plugin = array(
 | 
			
		||||
  'title' => t('Hide the administrative area'),
 | 
			
		||||
  'format callback' => 'addressfield_format_address_hide_administrative_area',
 | 
			
		||||
  'type' => 'address',
 | 
			
		||||
  'weight' => -84,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Format callback.
 | 
			
		||||
 *
 | 
			
		||||
 * @see CALLBACK_addressfield_format_callback()
 | 
			
		||||
 */
 | 
			
		||||
function addressfield_format_address_hide_administrative_area(&$format, $address, $context = array()) {
 | 
			
		||||
  if (isset($format['locality_block']['administrative_area'])) {
 | 
			
		||||
    $format['locality_block']['administrative_area']['#access'] = FALSE;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -20,7 +20,7 @@ $plugin = array(
 | 
			
		||||
function addressfield_format_address_hide_country(&$format, $address, $context = array()) {
 | 
			
		||||
  // Hide the country element only if the whole field is required, otherwise
 | 
			
		||||
  // there will always be an additional None option.
 | 
			
		||||
  if ($context['mode'] == 'form' && $context['instance']['required']) {
 | 
			
		||||
  if ($context['mode'] == 'form' && (empty($context['instance']) || $context['instance']['required'])) {
 | 
			
		||||
    if (!empty($format['country']['#options']) && count($format['country']['#options']) == 1) {
 | 
			
		||||
      $format['country']['#access'] =  FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,24 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Hide the locality field.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
$plugin = array(
 | 
			
		||||
  'title' => t('Hide the locality'),
 | 
			
		||||
  'format callback' => 'addressfield_format_address_hide_locality',
 | 
			
		||||
  'type' => 'address',
 | 
			
		||||
  'weight' => -84,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Format callback.
 | 
			
		||||
 *
 | 
			
		||||
 * @see CALLBACK_addressfield_format_callback()
 | 
			
		||||
 */
 | 
			
		||||
function addressfield_format_address_hide_locality(&$format, $address, $context = array()) {
 | 
			
		||||
  if (isset($format['locality_block']['locality'])) {
 | 
			
		||||
    $format['locality_block']['locality']['#access'] = FALSE;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -240,7 +240,12 @@ function addressfield_format_address_generate(&$format, $address, $context = arr
 | 
			
		||||
  if (in_array($address['country'], $countries_postal_code_after_locality)) {
 | 
			
		||||
    // Take the widget out of the array.
 | 
			
		||||
    $postal_code_widget = $format['locality_block']['postal_code'];
 | 
			
		||||
    $postal_code_widget['#prefix'] = ' ';
 | 
			
		||||
 | 
			
		||||
    // If the postal code not in its own row, add a separating space.
 | 
			
		||||
    if (empty($postal_code_widget['#tag'])) {
 | 
			
		||||
      $postal_code_widget['#prefix'] = ' ';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unset($format['locality_block']['postal_code']);
 | 
			
		||||
 | 
			
		||||
    // Add it back.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										0
									
								
								sites/all/modules/contrib/fields/autocomplete_deluxe/README.txt
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								sites/all/modules/contrib/fields/autocomplete_deluxe/README.txt
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										33
									
								
								sites/all/modules/contrib/fields/autocomplete_deluxe/autocomplete_deluxe.api.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										33
									
								
								sites/all/modules/contrib/fields/autocomplete_deluxe/autocomplete_deluxe.api.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@@ -1,5 +1,4 @@
 | 
			
		||||
<?php
 | 
			
		||||
// $Id$
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
@@ -12,24 +11,26 @@
 | 
			
		||||
 * When you want to use the Autocomplete Deluxe element, you have to choose
 | 
			
		||||
 * between two types sources for the suggestion data: Ajax Callbacks or Lists.
 | 
			
		||||
 * You can set the source type by using the appropriate options:
 | 
			
		||||
 * - #autocomplete_deluxe_path expects a string with an url, that points to the ajax
 | 
			
		||||
 *   callback. The response should be encoded as json(like for the core
 | 
			
		||||
 * - #autocomplete_deluxe_path expects a string with an url, that points to the
 | 
			
		||||
 *   ajax callback. The response should be encoded as json (like for the core
 | 
			
		||||
 *   autocomplete).
 | 
			
		||||
 * - #autocomplete_options needs an array in the form of an array(similar to #options in core
 | 
			
		||||
 *   for selects or checkboxes): array('a', 'b', 'c') or array(1 => 'a', 2 =>
 | 
			
		||||
 *   'b', 3 => 'c').
 | 
			
		||||
 * - #autocomplete_options needs an array in the form of an array (similar to
 | 
			
		||||
 *   #options in core for selects or checkboxes): array('a', 'b', 'c') or
 | 
			
		||||
 *   array(1 => 'a', 2 => 'b', 3 => 'c').
 | 
			
		||||
 *
 | 
			
		||||
 * Besides this two, there are three other options, wich autocomplete deluxe
 | 
			
		||||
 * Besides these two, there are four other options which autocomplete deluxe
 | 
			
		||||
 * accepts:
 | 
			
		||||
 * - #multiple Indicates whether the user may select more than one item. Expects
 | 
			
		||||
 *   TRUE or FALSE, by default it is set to FALSE.
 | 
			
		||||
 * - #autocomplete_multiple_delimiter If #multiple is TRUE, then you can use
 | 
			
		||||
 *   this option to set a seperator for multiple values. By default a string
 | 
			
		||||
 *   with the follwing content will be used: ', '.
 | 
			
		||||
 * - #autocomplete_min_length Indicates how many characters must be entered
 | 
			
		||||
 *   until, the suggesion list can be opened. Especially helpfull, when your
 | 
			
		||||
 * - #delimiter If #multiple is TRUE, then you can use this option to set a
 | 
			
		||||
 *   seperator for multiple values. By default a string with the following
 | 
			
		||||
 *   content will be used: ', '.
 | 
			
		||||
 * - #min_length Indicates how many characters must be entered
 | 
			
		||||
 *   until, the suggesion list can be opened. Especially helpful, when your
 | 
			
		||||
 *   ajax callback returns only valid suggestion for a minimum characters.
 | 
			
		||||
 *   The default is 0.
 | 
			
		||||
 * - #not_found_message A message text which will be displayed, if the entered
 | 
			
		||||
 *   term was not found.
 | 
			
		||||
 */
 | 
			
		||||
function somefunction() {
 | 
			
		||||
  switch ($type) {
 | 
			
		||||
@@ -38,16 +39,18 @@ function somefunction() {
 | 
			
		||||
        '#type' => 'autocomplete_deluxe',
 | 
			
		||||
        '#autocomplete_options' => $options,
 | 
			
		||||
        '#multiple' => FALSE,
 | 
			
		||||
        '#autocomplete_min_length' => 0,
 | 
			
		||||
        '#min_length' => 0,
 | 
			
		||||
      );
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case 'ajax':
 | 
			
		||||
      $element = array(
 | 
			
		||||
        '#type' => 'autocomplete_deluxe',
 | 
			
		||||
        '#autocomplete_deluxe_path' => url('some_uri', array('absolute' => TRUE)),
 | 
			
		||||
        '#multiple' => TRUE,
 | 
			
		||||
        '#autocomplete_min_length' => 1,
 | 
			
		||||
        '#autocomplete_multiple_delimiter' => '|',
 | 
			
		||||
        '#min_length' => 1,
 | 
			
		||||
        '#delimiter' => '|',
 | 
			
		||||
        '#not_found_message' => "The term '@term' will be added.",
 | 
			
		||||
      );
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										0
									
								
								sites/all/modules/contrib/fields/autocomplete_deluxe/autocomplete_deluxe.css
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								sites/all/modules/contrib/fields/autocomplete_deluxe/autocomplete_deluxe.css
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@@ -5,9 +5,9 @@ core = 7.x
 | 
			
		||||
files[] = autocomplete_deluxe.module
 | 
			
		||||
dependencies[] = taxonomy
 | 
			
		||||
 | 
			
		||||
; Information added by Drupal.org packaging script on 2017-01-11
 | 
			
		||||
version = "7.x-2.2"
 | 
			
		||||
; Information added by Drupal.org packaging script on 2017-07-25
 | 
			
		||||
version = "7.x-2.3"
 | 
			
		||||
core = "7.x"
 | 
			
		||||
project = "autocomplete_deluxe"
 | 
			
		||||
datestamp = "1484128687"
 | 
			
		||||
datestamp = "1501005546"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										0
									
								
								sites/all/modules/contrib/fields/autocomplete_deluxe/autocomplete_deluxe.js
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								sites/all/modules/contrib/fields/autocomplete_deluxe/autocomplete_deluxe.js
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								sites/all/modules/contrib/fields/autocomplete_deluxe/autocomplete_deluxe.module
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								sites/all/modules/contrib/fields/autocomplete_deluxe/autocomplete_deluxe.module
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@@ -1,9 +1,83 @@
 | 
			
		||||
 | 
			
		||||
Entity Translation 7.x-1.x, xxxx-xx-xx
 | 
			
		||||
--------------------------------------
 | 
			
		||||
#2189567 by stefanos.petrakis, jmuzz: Fixed problems enabling and disabling translation on
 | 
			
		||||
  a field with revisions enabled.
 | 
			
		||||
#2798721 by gnucifer: Path scheme not initialized on delete translation confirmation form.
 | 
			
		||||
#3025770 by sudheeshps, patelmayank7552, stefanos.petrakis: PHP 7.0
 | 
			
		||||
  Compatibility
 | 
			
		||||
#2536292 by plopesc, stefanos.petrakis: "Warning: array_merge(): Argument #2 is
 | 
			
		||||
  not an array in entity_translation_menu_alter" When 'page arguments' or
 | 
			
		||||
  'access arguments' are not defined in the original item
 | 
			
		||||
#2921298 by Stevel, stefanos.petrakis: Missing test dependencies
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Entity Translation 7.x-1.0, 2018-04-01
 | 
			
		||||
--------------------------------------
 | 
			
		||||
(no change)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Entity Translation 7.x-1.0-rc1, 2018-03-21
 | 
			
		||||
------------------------------------------
 | 
			
		||||
#2927815 by Skabbkladden, dawehner: Infinite loop with language neutral alias
 | 
			
		||||
  and pathauto.
 | 
			
		||||
#2890683 by tobiberlin, stefanos.petrakis: entity_translation_field_attach_form()
 | 
			
		||||
  adding unwanted fields to form.
 | 
			
		||||
#2907366 by swati.nuna: Invalid hook hook_translation_info() mentioned in
 | 
			
		||||
  docblock for entity_translation_edit_form_info().
 | 
			
		||||
#1799770 by plach, bforchhammer: Update id and bundle when setting a wrapped
 | 
			
		||||
  entity.
 | 
			
		||||
#2339315 by plach: Added documentation for
 | 
			
		||||
  hook_entity_translation_source_field_state_alter().
 | 
			
		||||
#1506054 by plach, Owen Barton: Taxonomy term reference: language-aware widget
 | 
			
		||||
  and autocomplete.
 | 
			
		||||
#2907275 by jalpesh: CSS class name misspelled in entity_translation_overview().
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Entity Translation 7.x-1.0-beta7, 2017-08-21
 | 
			
		||||
--------------------------------------------
 | 
			
		||||
#2903195 by stefanos.petrakis, BAHbKA, plach: Enabling translation for not
 | 
			
		||||
  empty taxonomy vocabulary.
 | 
			
		||||
#2425825 by jamesrward: Update from before beta4 fails.
 | 
			
		||||
#2900094 by joseph.olstad: code sniffer drupal.org recommended code syntax
 | 
			
		||||
  fixes.
 | 
			
		||||
#2883805 by mikran: entity_translation_update_7008 is broken when taxonomy
 | 
			
		||||
  module is not enabled.
 | 
			
		||||
#2877074 by plach, stefanos.petrakis, joseph.olstad: Refactor the
 | 
			
		||||
  entity_translation_language() callback to make it bundle-specific.
 | 
			
		||||
#2743685 by stefanos.petrakis, bwaindwain: Pathauto update for all translations
 | 
			
		||||
  for a single node.
 | 
			
		||||
#2899658 by joseph.olstad, stefanos.petrakis: entity_translation_upgrade_do
 | 
			
		||||
  needs to automatically create the entity_translation row for the source
 | 
			
		||||
  language in entity_translation.
 | 
			
		||||
#1800158 by meichr: Entity Translation Upgrade, drush extension.
 | 
			
		||||
#2885858 by StephaneQ: Can't delete taxonomy term translation since beta6
 | 
			
		||||
  update.
 | 
			
		||||
#2572203 by mattew: Wrong query generated when several Translations
 | 
			
		||||
  relationships are used.
 | 
			
		||||
#2824255 by ccarrascal, plach: Notice: Undefined index for language in
 | 
			
		||||
  setTranslation().
 | 
			
		||||
#2750179 by wadmiraal: Allowed default translation handler to be completely
 | 
			
		||||
  overridden.
 | 
			
		||||
#2307937 by meichr, joseph.olstad: Batch API needs $context['results'] handled
 | 
			
		||||
  as an array, not a value.
 | 
			
		||||
#1175170 by hgoto, Pisco, alberto56: Optionally enable disabled languages for
 | 
			
		||||
  entity translation.
 | 
			
		||||
#2870524 by stefanos.petrakis, joseph.olstad: Field copy fails with content
 | 
			
		||||
  translation for fields with entity translation enabled.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Entity Translation 7.x-1.0-beta6, 2017-03-03
 | 
			
		||||
--------------------------------------------
 | 
			
		||||
#2849464 by plach, czigor, stefanos.petrakis: Added an API to set the active
 | 
			
		||||
  language.
 | 
			
		||||
#2438615 by David_Rothstein, matthiasm11: New nodes are always created using
 | 
			
		||||
  LANGUAGE_NONE (only changed to the correct language during form submission).
 | 
			
		||||
#2820454 by Dylan Donkersgoed: PHP notice when attaching single field
 | 
			
		||||
  with field_attach_form.
 | 
			
		||||
#2826297 by Thomas Cys, dwebpoint, stefanos.petrakis: 'clone' is a reserved
 | 
			
		||||
  keyword introduced in PHP version 5.0 and cannot be invoked as a function.
 | 
			
		||||
#2189567 by stefanos.petrakis, jmuzz: Fixed problems enabling and disabling
 | 
			
		||||
  translation on a field with revisions enabled.
 | 
			
		||||
#2798721 by gnucifer: Path scheme not initialized on delete translation
 | 
			
		||||
  confirmation form.
 | 
			
		||||
#2215771 by colan, stefanos.petrakis: Fixed "Undefined index: translate in
 | 
			
		||||
  EntityTranslationDefaultHandler->entityForm()".
 | 
			
		||||
#1829636 by bforchhammer, stefanos.petrakis: Fixed "All languages" suffix not
 | 
			
		||||
 
 | 
			
		||||
@@ -9,8 +9,9 @@ Project maintainers
 | 
			
		||||
The Entity translation maintainers oversee the development of the project as a
 | 
			
		||||
whole. The project maintainers for Entity translation are:
 | 
			
		||||
 | 
			
		||||
- Francesco Placella 'plach' <http://drupal.org/user/183211>
 | 
			
		||||
- Daniel F. Kudwien 'sun' <http://drupal.org/user/54136>
 | 
			
		||||
- Francesco Placella 'plach' <https://www.drupal.org/u/plach>
 | 
			
		||||
- Daniel F. Kudwien 'sun' <https://www.drupal.org/u/sun>
 | 
			
		||||
- Stefanos Petrakis 'stefanos.petrakis' <https://www.drupal.org/u/stefanospetrakis>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Component maintainers
 | 
			
		||||
@@ -25,14 +26,15 @@ http://drupal.org/node/363367 to find out how to become a component maintainer.
 | 
			
		||||
Current component maintainers for Entity translation:
 | 
			
		||||
 | 
			
		||||
Base system
 | 
			
		||||
- Francesco Placella 'plach' <http://drupal.org/user/183211>
 | 
			
		||||
- Benedikt Forchhammer 'bforchhammer' <http://drupal.org/user/216396>
 | 
			
		||||
- Francesco Placella 'plach' <https://www.drupal.org/u/plach>
 | 
			
		||||
- Benedikt Forchhammer 'bforchhammer' <https://www.drupal.org/u/bforchhammer>
 | 
			
		||||
- Stefanos Petrakis 'stefanos.petrakis' <https://www.drupal.org/u/stefanospetrakis>
 | 
			
		||||
 | 
			
		||||
Menu integration
 | 
			
		||||
- Benedikt Forchhammer 'bforchhammer' <http://drupal.org/user/216396>
 | 
			
		||||
- Benedikt Forchhammer 'bforchhammer' <https://www.drupal.org/u/bforchhammer>
 | 
			
		||||
 | 
			
		||||
Views integration
 | 
			
		||||
- Fabian Sörqvist 'fabsor' <http://drupal.org/user/255704>
 | 
			
		||||
- Fabian Sörqvist 'fabsor' <https://www.drupal.org/u/fabsor>
 | 
			
		||||
 | 
			
		||||
Node translation upgrade
 | 
			
		||||
- Francesco Placella 'plach' <http://drupal.org/user/183211>
 | 
			
		||||
- Francesco Placella 'plach' <https://www.drupal.org/u/plach>
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,13 @@ function entity_translation_admin_form($form, $form_state) {
 | 
			
		||||
    '#default_value' => variable_get('locale_field_language_fallback', TRUE),
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  $form['entity_translation_languages_enabled'] = array(
 | 
			
		||||
    '#type' => 'checkbox',
 | 
			
		||||
    '#title' => t('Use only enabled languages'),
 | 
			
		||||
    '#description' => t('If checked, disabled languages will not show up as available languages. This setting does not apply to content types that are configured to use the Multilingual content (i18n_node) module as this module provides its own configuration.'),
 | 
			
		||||
    '#default_value' => variable_get('entity_translation_languages_enabled', FALSE),
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  $form['entity_translation_show_fallback_on_overview_pages'] = array(
 | 
			
		||||
    '#type' => 'checkbox',
 | 
			
		||||
    '#title' => t('Show fallback statuses on overview pages'),
 | 
			
		||||
@@ -45,7 +52,7 @@ function entity_translation_admin_form($form, $form_state) {
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  $_null = NULL;
 | 
			
		||||
  list($items, ) = menu_router_build();
 | 
			
		||||
  list($items,) = menu_router_build();
 | 
			
		||||
  _entity_translation_validate_path_schemes($_null, FALSE, $items);
 | 
			
		||||
 | 
			
		||||
  foreach (entity_get_info() as $entity_type => $info) {
 | 
			
		||||
@@ -316,7 +323,7 @@ function entity_translation_overview($entity_type, $entity, $callback = NULL) {
 | 
			
		||||
          $link = isset($add_links->links[$langcode]['href']) ? $add_links->links[$langcode] : array('href' => $add_path, 'language' => $language);
 | 
			
		||||
          $link['query'] = isset($_GET['destination']) ? drupal_get_destination() : FALSE;
 | 
			
		||||
          $options[] = $translatable ? l(t('add'), $link['href'], $link) : t('No translatable fields');
 | 
			
		||||
          $classes[] = $translatable ? '' : 'non-traslatable';
 | 
			
		||||
          $classes[] = $translatable ? '' : 'non-translatable';
 | 
			
		||||
        }
 | 
			
		||||
        $status = t('Not translated');
 | 
			
		||||
        // Show fallback information if required.
 | 
			
		||||
@@ -389,7 +396,7 @@ function _entity_translation_label($entity_type, $entity, $langcode = NULL) {
 | 
			
		||||
/**
 | 
			
		||||
 * Theme wrapper for the entity translation language page.
 | 
			
		||||
 */
 | 
			
		||||
function theme_entity_translation_overview($variables){
 | 
			
		||||
function theme_entity_translation_overview($variables) {
 | 
			
		||||
  $rows = $variables['rows'];
 | 
			
		||||
  return theme('table', array(
 | 
			
		||||
    'rows' => $rows,
 | 
			
		||||
@@ -400,7 +407,7 @@ function theme_entity_translation_overview($variables){
 | 
			
		||||
/**
 | 
			
		||||
 * Theme wrapper for the entity translation language outdated translation.
 | 
			
		||||
 */
 | 
			
		||||
function theme_entity_translation_overview_outdated($variables){
 | 
			
		||||
function theme_entity_translation_overview_outdated($variables) {
 | 
			
		||||
  $message = $variables['message'];
 | 
			
		||||
  return ' - <span class="marker">' . $message . '</span>';
 | 
			
		||||
}
 | 
			
		||||
@@ -410,7 +417,7 @@ function theme_entity_translation_overview_outdated($variables){
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_delete_confirm($form, $form_state, $entity_type, $entity, $langcode) {
 | 
			
		||||
  $handler = entity_translation_get_handler($entity_type, $entity);
 | 
			
		||||
  $handler->setFormLanguage($langcode);
 | 
			
		||||
  $handler->setActiveLanguage($langcode);
 | 
			
		||||
  $handler->initPathScheme();
 | 
			
		||||
  $languages = language_list();
 | 
			
		||||
 | 
			
		||||
@@ -452,7 +459,7 @@ function entity_translation_delete_confirm_submit($form, &$form_state) {
 | 
			
		||||
  $form_state['redirect'] = $handler->getTranslatePath();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
/**
 | 
			
		||||
 * Confirm form for changing field translatability.
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_translatable_form($form, &$form_state, $field_name) {
 | 
			
		||||
@@ -547,7 +554,7 @@ function entity_translation_translatable_form_submit($form, $form_state) {
 | 
			
		||||
  batch_set($batch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
/**
 | 
			
		||||
 * Toggle translatability of the given field.
 | 
			
		||||
 *
 | 
			
		||||
 * This is called from a batch operation, but should only run once per field.
 | 
			
		||||
@@ -602,12 +609,28 @@ function entity_translation_translatable_batch($translatable, $field_name, $copy
 | 
			
		||||
    ->range($offset, $limit)
 | 
			
		||||
    ->execute();
 | 
			
		||||
 | 
			
		||||
  foreach ($result as $entity_type => $revisions) {
 | 
			
		||||
    foreach ($revisions as $revision) {
 | 
			
		||||
      // $revision is a partial entity object that will be used as an array of
 | 
			
		||||
      // conditions.
 | 
			
		||||
      $conditions = (array) $revision;
 | 
			
		||||
      $entity = reset(entity_load($entity_type, FALSE, $conditions));
 | 
			
		||||
  foreach ($result as $entity_type => $partial_entities) {
 | 
			
		||||
 | 
			
		||||
    // Load all revisionable entities' revisions.
 | 
			
		||||
    if (EntityTranslationDefaultHandler::isEntityTypeRevisionable($entity_type)) {
 | 
			
		||||
      $entities = array();
 | 
			
		||||
      // Extract the revision identifier from the entity's definition.
 | 
			
		||||
      $entity_info = entity_get_info($entity_type);
 | 
			
		||||
      $revision_id_key = $entity_info['entity keys']['revision'];
 | 
			
		||||
      // Load each revisionable entity's revision using $conditions, which
 | 
			
		||||
      // should include the revision id information.
 | 
			
		||||
      foreach ($partial_entities as $partial_entity) {
 | 
			
		||||
        $conditions = (array) $partial_entity;
 | 
			
		||||
        $revision_condition = array_intersect_key($conditions, array($revision_id_key => $revision_id_key));
 | 
			
		||||
        $entity_revisions = entity_load($entity_type, FALSE, $revision_condition);
 | 
			
		||||
        $entities[] = reset($entity_revisions);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      $entities = entity_load($entity_type, array_keys($partial_entities));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    foreach ($entities as $entity) {
 | 
			
		||||
      $context['sandbox']['progress']++;
 | 
			
		||||
      $handler = entity_translation_get_handler($entity_type, $entity);
 | 
			
		||||
      $langcode = $handler->getLanguage();
 | 
			
		||||
@@ -626,9 +649,10 @@ function entity_translation_translatable_batch($translatable, $field_name, $copy
 | 
			
		||||
      if ($translatable && isset($entity->{$field_name}[LANGUAGE_NONE])) {
 | 
			
		||||
        // If the field is being switched to translatable and has data for
 | 
			
		||||
        // LANGUAGE_NONE then we need to move the data to the right language.
 | 
			
		||||
 | 
			
		||||
        // In case the 'Copy translations' option was selected, move the
 | 
			
		||||
        // available LANGUAGE_NONE field data into all existing translation
 | 
			
		||||
        // languages, otherwise only into the entity's language.
 | 
			
		||||
        $translations = $handler->getTranslations();
 | 
			
		||||
 | 
			
		||||
        if ($copy_all_languages && !empty($translations->data)) {
 | 
			
		||||
          foreach ($translations->data as $translation) {
 | 
			
		||||
            $entity->{$field_name}[$translation['language']] = $entity->{$field_name}[LANGUAGE_NONE];
 | 
			
		||||
 
 | 
			
		||||
@@ -164,3 +164,17 @@ function hook_entity_translation_delete($entity_type, $entity, $langcode) {
 | 
			
		||||
 */
 | 
			
		||||
function hook_entity_translation_delete_revision($entity_type, $entity, $langcode) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Allows to sets the right values in the form state when adding a translation.
 | 
			
		||||
 */
 | 
			
		||||
function hook_entity_translation_source_field_state_alter(&$field_state) {
 | 
			
		||||
  if (isset($field_state['entity'])) {
 | 
			
		||||
    module_load_include('inc', 'entity', 'includes/entity.ui');
 | 
			
		||||
    foreach ($field_state['entity'] as $delta => $entity) {
 | 
			
		||||
      if ($entity instanceof FieldCollectionItemEntity) {
 | 
			
		||||
        $field_state['entity'][$delta] = entity_ui_clone_entity('field_collection_item', $entity);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,9 @@ core = 7.x
 | 
			
		||||
configure = admin/config/regional/entity_translation
 | 
			
		||||
dependencies[] = locale (>7.14)
 | 
			
		||||
 | 
			
		||||
test_dependencies[] = pathauto:pathauto
 | 
			
		||||
test_dependencies[] = title:title
 | 
			
		||||
 | 
			
		||||
files[] = includes/translation.handler_factory.inc
 | 
			
		||||
files[] = includes/translation.handler.inc
 | 
			
		||||
files[] = includes/translation.handler.comment.inc
 | 
			
		||||
@@ -23,9 +26,8 @@ files[] = views/entity_translation_handler_filter_language.inc
 | 
			
		||||
files[] = views/entity_translation_handler_filter_translation_exists.inc
 | 
			
		||||
files[] = views/entity_translation_handler_field_field.inc
 | 
			
		||||
 | 
			
		||||
; Information added by Drupal.org packaging script on 2016-09-28
 | 
			
		||||
version = "7.x-1.0-beta5+15-dev"
 | 
			
		||||
; Information added by Drupal.org packaging script on 2019-01-20
 | 
			
		||||
version = "7.x-1.0+5-dev"
 | 
			
		||||
core = "7.x"
 | 
			
		||||
project = "entity_translation"
 | 
			
		||||
datestamp = "1475057941"
 | 
			
		||||
 | 
			
		||||
datestamp = "1548022384"
 | 
			
		||||
 
 | 
			
		||||
@@ -175,6 +175,9 @@ function entity_translation_install() {
 | 
			
		||||
 | 
			
		||||
  // Enable revision support for entity translation.
 | 
			
		||||
  variable_set('entity_translation_revision_enabled', TRUE);
 | 
			
		||||
 | 
			
		||||
  // Enable taxonomy autocomplete support.
 | 
			
		||||
  variable_set('entity_translation_taxonomy_autocomplete', TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -356,7 +359,11 @@ function entity_translation_update_7006() {
 | 
			
		||||
    'not null' => FALSE,
 | 
			
		||||
    'description' => 'The entity revision id this translation relates to',
 | 
			
		||||
  );
 | 
			
		||||
  db_add_field('entity_translation', 'revision_id', $spec);
 | 
			
		||||
 | 
			
		||||
  // Create revision id column if it doesn't exist already.
 | 
			
		||||
  if (!db_field_exists('entity_translation', 'revision_id')) {
 | 
			
		||||
    db_add_field('entity_translation', 'revision_id', $spec);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Create the entity translation revision schema.
 | 
			
		||||
  $table = array(
 | 
			
		||||
@@ -429,7 +436,11 @@ function entity_translation_update_7006() {
 | 
			
		||||
    'primary key' => array('entity_type', 'revision_id', 'language'),
 | 
			
		||||
    'indexes'=> array('revision_id' => array('revision_id')),
 | 
			
		||||
  );
 | 
			
		||||
  db_create_table('entity_translation_revision', $table);
 | 
			
		||||
 | 
			
		||||
  // Create entity translation revision table if it doesn't exist already.
 | 
			
		||||
  if (!db_table_exists('entity_translation_revision')) {
 | 
			
		||||
    db_create_table('entity_translation_revision', $table);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -452,6 +463,9 @@ function entity_translation_update_7007() {
 | 
			
		||||
 * through it.
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_update_7008() {
 | 
			
		||||
  if (!module_exists('taxonomy')) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  // According to EXPLAIN joining {taxonomy_vocabulary} here makes the query
 | 
			
		||||
  // perform way worse, so we just split into two quick ones.
 | 
			
		||||
  $query = "SELECT t.vid
 | 
			
		||||
 
 | 
			
		||||
@@ -244,6 +244,13 @@ function entity_translation_menu() {
 | 
			
		||||
    'file' => 'entity_translation.admin.inc',
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  $items['entity_translation/taxonomy_term/autocomplete'] = array(
 | 
			
		||||
    'title' => 'Entity translation autocomplete',
 | 
			
		||||
    'page callback' => 'entity_translation_taxonomy_term_autocomplete',
 | 
			
		||||
    'access arguments' => array('access content'),
 | 
			
		||||
    'type' => MENU_CALLBACK,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return $items;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -457,7 +464,11 @@ function entity_translation_menu_alter(&$items) {
 | 
			
		||||
          // Replace the main edit callback with our proxy implementation to set
 | 
			
		||||
          // form language to the current language and check access.
 | 
			
		||||
          $entity_position = array_search($scheme['path wildcard'], $edit_path_parts);
 | 
			
		||||
          $original_item = $edit_item;
 | 
			
		||||
          // Make sure incoming page and access arguments are arrays.
 | 
			
		||||
          $original_item = $edit_item + array(
 | 
			
		||||
            'page arguments' => array(),
 | 
			
		||||
            'access arguments' => array(),
 | 
			
		||||
          );
 | 
			
		||||
          $args = array($entity_type, $entity_position, FALSE, $original_item);
 | 
			
		||||
          $edit_item['page callback'] = 'entity_translation_edit_page';
 | 
			
		||||
          $edit_item['page arguments'] = array_merge($args, $original_item['page arguments']);
 | 
			
		||||
@@ -550,7 +561,7 @@ function entity_translation_edit_page() {
 | 
			
		||||
  $handler = entity_translation_get_handler($entity_type, $entity);
 | 
			
		||||
  $handler->initPathScheme();
 | 
			
		||||
  $langcode = entity_translation_get_existing_language($entity_type, $entity, $langcode);
 | 
			
		||||
  $handler->setFormLanguage($langcode);
 | 
			
		||||
  $handler->setActiveLanguage($langcode);
 | 
			
		||||
 | 
			
		||||
  // Display the entity edit form.
 | 
			
		||||
  return _entity_translation_callback($edit_form_item['page callback'], $args, $edit_form_item);
 | 
			
		||||
@@ -693,7 +704,7 @@ function entity_translation_add_page() {
 | 
			
		||||
 | 
			
		||||
  $handler = entity_translation_get_handler($entity_type, $entity);
 | 
			
		||||
  $handler->initPathScheme();
 | 
			
		||||
  $handler->setFormLanguage($langcode);
 | 
			
		||||
  $handler->setActiveLanguage($langcode);
 | 
			
		||||
  $handler->setSourceLanguage($source);
 | 
			
		||||
 | 
			
		||||
  // Display the entity edit form.
 | 
			
		||||
@@ -918,7 +929,7 @@ function entity_translation_field_language_alter(&$display_language, $context) {
 | 
			
		||||
    if (isset($translations->data[$context['language']]) && !entity_translation_access($entity_type, $translations->data[$context['language']])) {
 | 
			
		||||
      list(, , $bundle) = entity_extract_ids($entity_type, $entity);
 | 
			
		||||
      $instances = field_info_instances($entity_type, $bundle);
 | 
			
		||||
      $entity = clone($entity);
 | 
			
		||||
      $entity = clone $entity;
 | 
			
		||||
 | 
			
		||||
      foreach ($translations->data as $langcode => $translation) {
 | 
			
		||||
        if ($langcode == $context['language'] || !entity_translation_access($entity_type, $translations->data[$langcode])) {
 | 
			
		||||
@@ -1194,7 +1205,7 @@ function entity_translation_field_attach_form($entity_type, $entity, &$form, &$f
 | 
			
		||||
  if (empty($form['#entity_translation_source_form']) && entity_translation_enabled($entity_type, $bundle)) {
 | 
			
		||||
    $handler = entity_translation_get_handler($entity_type, $entity);
 | 
			
		||||
    $langcode = !empty($langcode) ? $langcode : $handler->getLanguage();
 | 
			
		||||
    $form_langcode = $handler->getFormLanguage();
 | 
			
		||||
    $form_langcode = $handler->getActiveLanguage();
 | 
			
		||||
    $translations = $handler->getTranslations();
 | 
			
		||||
    $update_langcode = $form_langcode && ($form_langcode != $langcode);
 | 
			
		||||
    $source = $handler->getSourceLanguage();
 | 
			
		||||
@@ -1217,7 +1228,7 @@ function entity_translation_field_attach_form($entity_type, $entity, &$form, &$f
 | 
			
		||||
        // language information from source to target language, this way the
 | 
			
		||||
        // user can find the form items already populated with the source values
 | 
			
		||||
        // while the field form element holds the correct language information.
 | 
			
		||||
        if ($field['translatable']) {
 | 
			
		||||
        if ($field['translatable'] && isset($form[$field_name])) {
 | 
			
		||||
          $element = &$form[$field_name];
 | 
			
		||||
          $element['#entity_type'] = $entity_type;
 | 
			
		||||
          $element['#entity'] = $entity;
 | 
			
		||||
@@ -1253,11 +1264,14 @@ function entity_translation_field_attach_form($entity_type, $entity, &$form, &$f
 | 
			
		||||
      list(, , $bundle) = entity_extract_ids($entity_type, $entity);
 | 
			
		||||
      foreach (field_info_instances($entity_type, $bundle) as $instance) {
 | 
			
		||||
        $field_name = $instance['field_name'];
 | 
			
		||||
        $field = field_info_field($field_name);
 | 
			
		||||
        // If access is not set or is granted we check whether the user has
 | 
			
		||||
        // access to shared fields.
 | 
			
		||||
        $form[$field_name]['#access'] = (!isset($form[$field_name]['#access']) || $form[$field_name]['#access']) && ($field['translatable'] || $shared_access);
 | 
			
		||||
        $form[$field_name]['#multilingual'] = (boolean) $field['translatable'];
 | 
			
		||||
        // Check if a field is part of the form array.
 | 
			
		||||
        if (isset($form[$field_name])) {
 | 
			
		||||
          $field = field_info_field($field_name);
 | 
			
		||||
          // If access is not set or is granted we check whether the user has
 | 
			
		||||
          // access to shared fields.
 | 
			
		||||
          $form[$field_name]['#access'] = (!isset($form[$field_name]['#access']) || $form[$field_name]['#access']) && ($field['translatable'] || $shared_access);
 | 
			
		||||
          $form[$field_name]['#multilingual'] = (boolean) $field['translatable'];
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1491,7 +1505,7 @@ function entity_translation_form_alter(&$form, &$form_state) {
 | 
			
		||||
      if (!$handler->isNewEntity()) {
 | 
			
		||||
        $handler->entityForm($form, $form_state);
 | 
			
		||||
        $translations = $handler->getTranslations();
 | 
			
		||||
        $form_langcode = $handler->getFormLanguage();
 | 
			
		||||
        $form_langcode = $handler->getActiveLanguage();
 | 
			
		||||
        if (!isset($translations->data[$form_langcode]) || count($translations->data) > 1) {
 | 
			
		||||
          // Hide shared form elements if the user is not allowed to edit them.
 | 
			
		||||
          $handler->entityFormSharedElements($form);
 | 
			
		||||
@@ -1520,7 +1534,7 @@ function entity_translation_form_alter(&$form, &$form_state) {
 | 
			
		||||
function entity_translation_entity_form_source_language_submit($form, &$form_state) {
 | 
			
		||||
  $handler = entity_translation_entity_form_get_handler($form, $form_state);
 | 
			
		||||
  $langcode = $form_state['values']['source_language']['language'];
 | 
			
		||||
  $path = "{$handler->getEditPath()}/add/$langcode/{$handler->getFormLanguage()}";
 | 
			
		||||
  $path = "{$handler->getEditPath()}/add/$langcode/{$handler->getActiveLanguage()}";
 | 
			
		||||
  $options = array();
 | 
			
		||||
  if (isset($_GET['destination'])) {
 | 
			
		||||
    $options['query'] = drupal_get_destination();
 | 
			
		||||
@@ -1536,7 +1550,7 @@ function entity_translation_entity_form_source_language_submit($form, &$form_sta
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_entity_form_delete_translation_submit($form, &$form_state) {
 | 
			
		||||
  $handler = entity_translation_entity_form_get_handler($form, $form_state);
 | 
			
		||||
  $path = "{$handler->getTranslatePath()}/delete/{$handler->getFormLanguage()}";
 | 
			
		||||
  $path = "{$handler->getTranslatePath()}/delete/{$handler->getActiveLanguage()}";
 | 
			
		||||
  $options = array();
 | 
			
		||||
  if (isset($_GET['destination'])) {
 | 
			
		||||
    $options['query'] = drupal_get_destination();
 | 
			
		||||
@@ -1564,7 +1578,7 @@ function entity_translation_entity_form_language_update($element, &$form_state,
 | 
			
		||||
  // needed when responding to an AJAX request where the languages cannot be set
 | 
			
		||||
  // from the usual page callback.
 | 
			
		||||
  if (!empty($form_state['entity_translation']['form_langcode'])) {
 | 
			
		||||
    $handler->setFormLanguage($form_state['entity_translation']['form_langcode']);
 | 
			
		||||
    $handler->setActiveLanguage($form_state['entity_translation']['form_langcode']);
 | 
			
		||||
  }
 | 
			
		||||
  // When responding to an AJAX request we should ignore any change in the
 | 
			
		||||
  // language widget as it may alter the field language expected by the AJAX
 | 
			
		||||
@@ -1597,6 +1611,9 @@ function entity_translation_field_attach_submit($entity_type, $entity, $form, &$
 | 
			
		||||
    // Update the wrapped entity with the submitted values.
 | 
			
		||||
    $handler->setEntity($entity);
 | 
			
		||||
    $handler->entityFormSubmit($form, $form_state);
 | 
			
		||||
 | 
			
		||||
    // Process in-place translations for the taxonomy autocomplete widget.
 | 
			
		||||
    entity_translation_taxonomy_term_field_attach_submit($entity_type, $entity, $form, $form_state);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1671,7 +1688,7 @@ function theme_entity_translation_language_tabs($variables) {
 | 
			
		||||
 * Adds an option to enable field synchronization.
 | 
			
		||||
 * Enable a selector to choose whether a field is translatable.
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_form_field_ui_field_edit_form_alter(&$form, $form_state) {
 | 
			
		||||
function entity_translation_form_field_ui_field_edit_form_alter(&$form, &$form_state) {
 | 
			
		||||
  $instance = $form['#instance'];
 | 
			
		||||
  $entity_type = $instance['entity_type'];
 | 
			
		||||
  $field_name = $instance['field_name'];
 | 
			
		||||
@@ -1691,7 +1708,8 @@ function entity_translation_form_field_ui_field_edit_form_alter(&$form, $form_st
 | 
			
		||||
  $label = t('Field translation');
 | 
			
		||||
  $title = t('Users may translate all occurrences of this field:') . _entity_translation_field_desc($field);
 | 
			
		||||
 | 
			
		||||
  if (field_has_data($field)) {
 | 
			
		||||
  $form_state['field_has_data'] = field_has_data($field);
 | 
			
		||||
  if ($form_state['field_has_data']) {
 | 
			
		||||
    $path = "admin/config/regional/entity_translation/translatable/$field_name";
 | 
			
		||||
    $status = $translatable ? $title : (t('All occurrences of this field are untranslatable:') . _entity_translation_field_desc($field));
 | 
			
		||||
    $link_title = !$translatable ? t('Enable translation') : t('Disable translation');
 | 
			
		||||
@@ -1719,6 +1737,11 @@ function entity_translation_form_field_ui_field_edit_form_alter(&$form, $form_st
 | 
			
		||||
      '#default_value' => $translatable,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  $function = 'entity_translation_form_field_ui_field_edit_' . $instance['widget']['type'] . '_form_alter';
 | 
			
		||||
  if (function_exists($function)) {
 | 
			
		||||
    $function($form, $form_state);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -1821,32 +1844,37 @@ function entity_translation_settings($entity_type, $bundle) {
 | 
			
		||||
 * Entity language callback.
 | 
			
		||||
 *
 | 
			
		||||
 * This callback changes the entity language from the actual one to the active
 | 
			
		||||
 * form language. This overriding allows to obtain language dependent form
 | 
			
		||||
 * widgets where multilingual values are supported (e.g. field or path alias
 | 
			
		||||
 * widgets) even if the code was not originally written with supporting multiple
 | 
			
		||||
 * values per language in mind.
 | 
			
		||||
 * language. This overriding allows to obtain language dependent form widgets
 | 
			
		||||
 * where multilingual values are supported (e.g. field or path alias widgets)
 | 
			
		||||
 * even if the code was not originally written with supporting multiple values
 | 
			
		||||
 * per language in mind.
 | 
			
		||||
 *
 | 
			
		||||
 * The main drawback of this approach is that code needing to access the actual
 | 
			
		||||
 * language in the entity form build/validation/submit workflow cannot rely on
 | 
			
		||||
 * the entity_language() function. On the other hand in these scenarios assuming
 | 
			
		||||
 * the presence of Entity translation should be safe, thus being able to rely on
 | 
			
		||||
 * the EntityTranslationHandlerInterface::getLanguage() method.
 | 
			
		||||
 * the presence of Entity translation should be safe, thus developers can rely
 | 
			
		||||
 * on the EntityTranslationHandlerInterface::getLanguage() method.
 | 
			
		||||
 *
 | 
			
		||||
 * @param $entity_type
 | 
			
		||||
 * @param string $entity_type
 | 
			
		||||
 *    The the type of the entity.
 | 
			
		||||
 * @param $entity
 | 
			
		||||
 * @param object $entity
 | 
			
		||||
 *    The entity whose language has to be returned.
 | 
			
		||||
 *
 | 
			
		||||
 * @return
 | 
			
		||||
 * @return string
 | 
			
		||||
 *   A valid language code.
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_language($entity_type, $entity) {
 | 
			
		||||
  $handler = entity_translation_get_handler($entity_type, $entity);
 | 
			
		||||
  if (empty($handler)) {
 | 
			
		||||
  if (!$handler) {
 | 
			
		||||
    return LANGUAGE_NONE;
 | 
			
		||||
  }
 | 
			
		||||
  $langcode = $handler->getFormLanguage();
 | 
			
		||||
  return !empty($langcode) ? $langcode : $handler->getLanguage();
 | 
			
		||||
  if (entity_translation_enabled($entity_type, $entity)) {
 | 
			
		||||
    $langcode = $handler->getActiveLanguage();
 | 
			
		||||
    return $langcode ? $langcode : $handler->getLanguage();
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    return $handler->getLanguage();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -1862,15 +1890,8 @@ function entity_translation_language($entity_type, $entity) {
 | 
			
		||||
 *   A class implementing EntityTranslationHandlerInterface.
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_get_handler($entity_type = NULL, $entity = NULL) {
 | 
			
		||||
  if (class_exists('EntityTranslationHandlerFactory')) {
 | 
			
		||||
    $factory = EntityTranslationHandlerFactory::getInstance();
 | 
			
		||||
    return empty($entity) ? $factory->getLastHandler($entity_type) : $factory->getHandler($entity_type, $entity);
 | 
			
		||||
  }
 | 
			
		||||
  // @todo BC layer. Remove before the first stable release.
 | 
			
		||||
  elseif (!empty($entity_type) && is_object($entity)) {
 | 
			
		||||
    $entity_info = entity_get_info($entity_type);
 | 
			
		||||
    return new EntityTranslationDefaultHandler($entity_type, $entity_info, $entity);
 | 
			
		||||
  }
 | 
			
		||||
  $factory = EntityTranslationHandlerFactory::getInstance();
 | 
			
		||||
  return empty($entity) ? $factory->getLastHandler($entity_type) : $factory->getHandler($entity_type, $entity);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -1915,7 +1936,7 @@ function entity_translation_current_form_get_handler() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns an array of edit form info as defined in hook_translation_info().
 | 
			
		||||
 * Returns an array of edit form info as defined in hook_entity_info().
 | 
			
		||||
 *
 | 
			
		||||
 * @param $form
 | 
			
		||||
 *   The entity edit form.
 | 
			
		||||
@@ -2027,7 +2048,7 @@ function entity_translation_entity_uuid_presave(&$entity, $entity_type) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implement hook_pathauto_alias_alter().
 | 
			
		||||
 * Implements hook_pathauto_alias_alter().
 | 
			
		||||
 *
 | 
			
		||||
 * When bulk-updating aliases for nodes automatically create a path for every
 | 
			
		||||
 * translation.
 | 
			
		||||
@@ -2037,17 +2058,20 @@ function entity_translation_pathauto_alias_alter(&$alias, array &$context) {
 | 
			
		||||
  $entity_type = $context['module'];
 | 
			
		||||
 | 
			
		||||
  // Ensure that we are dealing with a bundle having entity translation enabled.
 | 
			
		||||
  if ($context['op'] == 'bulkupdate' && !empty($info[$entity_type]['token type']) && !empty($context['data'][$info[$entity_type]['token type']])) {
 | 
			
		||||
  if (in_array($context['op'], array('bulkupdate', 'update')) && !empty($info[$entity_type]['token type']) && !empty($context['data'][$info[$entity_type]['token type']])) {
 | 
			
		||||
    $entity = $context['data'][$info[$entity_type]['token type']];
 | 
			
		||||
    if (entity_translation_enabled($entity_type, $entity)) {
 | 
			
		||||
      $translations = entity_translation_get_handler($entity_type, $entity)->getTranslations();
 | 
			
		||||
      // Only create extra aliases if we are working on the original language to
 | 
			
		||||
      // avoid infinite recursion.
 | 
			
		||||
      if ($context['language'] == $translations->original) {
 | 
			
		||||
      // To avoid infinite recursion, remember the starting language.
 | 
			
		||||
      static $pathauto_start_language;
 | 
			
		||||
      if (!$pathauto_start_language) {
 | 
			
		||||
        $pathauto_start_language = $context['language'];
 | 
			
		||||
      }
 | 
			
		||||
      if ($context['language'] == $pathauto_start_language && $context['language'] != LANGUAGE_NONE) {
 | 
			
		||||
        foreach ($translations->data as $language => $translation) {
 | 
			
		||||
          // We already have an alias for the original language, so let's not
 | 
			
		||||
          // We already have an alias for the starting language, so let's not
 | 
			
		||||
          // create another one.
 | 
			
		||||
          if ($language == $translations->original) {
 | 
			
		||||
          if ($language == $pathauto_start_language) {
 | 
			
		||||
            continue;
 | 
			
		||||
          }
 | 
			
		||||
          pathauto_create_alias($entity_type, $context['op'], $context['source'], $context['data'], $context['type'], $language);
 | 
			
		||||
@@ -2085,3 +2109,11 @@ function entity_translation_entity_save($entity_type, $entity) {
 | 
			
		||||
    field_attach_update($entity_type, $entity);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_field_attach_prepare_translation_alter().
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_field_attach_prepare_translation_alter(&$entity, $context) {
 | 
			
		||||
  $handler = entity_translation_get_handler('node', $entity);
 | 
			
		||||
  $handler->setActiveLanguage($context['langcode']);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -40,6 +40,9 @@ function entity_translation_taxonomy_term_menu_alter(&$items, $backup) {
 | 
			
		||||
  $items['taxonomy/term/%taxonomy_term/translate']['access callback'] = 'entity_translation_taxonomy_term_tab_access';
 | 
			
		||||
  $items['taxonomy/term/%taxonomy_term/translate']['file'] = 'entity_translation.admin.inc';
 | 
			
		||||
  $items['taxonomy/term/%taxonomy_term/translate']['module'] = 'entity_translation';
 | 
			
		||||
 | 
			
		||||
  // Delete translation callback.
 | 
			
		||||
  $items['taxonomy/term/%taxonomy_term/translate/delete/%entity_translation_language']['access arguments'] = $access_arguments;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -94,3 +97,472 @@ function entity_translation_form_taxonomy_form_vocabulary_submit($form, &$form_s
 | 
			
		||||
  variable_set('entity_translation_taxonomy', $info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns a translated label for the specified taxonomy term.
 | 
			
		||||
 *
 | 
			
		||||
 * @param object $term
 | 
			
		||||
 *   A taxonomy term object.
 | 
			
		||||
 * @param string $langcode
 | 
			
		||||
 *   The language the label should be translated in.
 | 
			
		||||
 *
 | 
			
		||||
 * @return string
 | 
			
		||||
 *   The translated taxonomy term label.
 | 
			
		||||
 *
 | 
			
		||||
 * @internal This is supposed to be used only by the ET taxonomy integration
 | 
			
		||||
 *   code, as it might be removed/replaced in any moment of the ET lifecycle.
 | 
			
		||||
 */
 | 
			
		||||
function _entity_translation_taxonomy_label($term, $langcode) {
 | 
			
		||||
  $entity_type = 'taxonomy_term';
 | 
			
		||||
  if (function_exists('title_entity_label')) {
 | 
			
		||||
    $label = title_entity_label($term, $entity_type, $langcode);
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    $label = entity_label($entity_type, $term);
 | 
			
		||||
  }
 | 
			
		||||
  return (string) $label;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements entity_translation_form_field_ui_field_edit_WIDGET_TYPE_form_alter().
 | 
			
		||||
 *
 | 
			
		||||
 * {@inheritdoc}
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_form_field_ui_field_edit_taxonomy_autocomplete_form_alter(&$form, &$form_state) {
 | 
			
		||||
  $key = 'entity_translation_taxonomy_autocomplete_translate';
 | 
			
		||||
  $instance = $form['#instance'];
 | 
			
		||||
  $field_name = $instance['field_name'];
 | 
			
		||||
  $entity_type = $instance['entity_type'];
 | 
			
		||||
  $field = field_info_field($field_name);
 | 
			
		||||
  $translatable = field_is_translatable($entity_type, $field);
 | 
			
		||||
  $bundle = !empty($field['settings']['allowed_values'][0]['vocabulary']) ? $field['settings']['allowed_values'][0]['vocabulary'] : NULL;
 | 
			
		||||
  $access = variable_get('entity_translation_taxonomy_autocomplete', FALSE);
 | 
			
		||||
 | 
			
		||||
  // Add a checkbox to toggle in-place translation for autocomplete widgets.
 | 
			
		||||
  $form['instance']['settings'][$key] = array(
 | 
			
		||||
    '#type' => 'checkbox',
 | 
			
		||||
    '#title' => t('Enable in-place translation of terms'),
 | 
			
		||||
    '#description' => t('Check this option if you wish to use translation forms to perform in-place translation for terms entered in the original language.'),
 | 
			
		||||
    '#default_value' => !$translatable && !empty($form['#instance']['settings'][$key]),
 | 
			
		||||
    '#access' => $access && (!$form_state['field_has_data'] || !$translatable) && entity_translation_enabled('taxonomy_term', $bundle),
 | 
			
		||||
    '#states' => array(
 | 
			
		||||
      'visible' => array(':input[name="field[translatable]"]' => array('checked' => FALSE)),
 | 
			
		||||
    ),
 | 
			
		||||
    '#weight' => -8,
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether in-place translation is enabled for the autocomplete widget.
 | 
			
		||||
 *
 | 
			
		||||
 * @param array $element
 | 
			
		||||
 *   The widget form element.
 | 
			
		||||
 * @param array $form_state
 | 
			
		||||
 *   The form state array.
 | 
			
		||||
 *
 | 
			
		||||
 * @return bool
 | 
			
		||||
 *   TRUE if in-place translation is enabled, FALSE otherwise.
 | 
			
		||||
 */
 | 
			
		||||
function _entity_translation_taxonomy_autocomplete_translation_enabled($element, $form_state) {
 | 
			
		||||
  $field = field_info_field($element['#field_name']);
 | 
			
		||||
  if (field_is_translatable($element['#entity_type'], $field)) {
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  list($id, , $bundle) = entity_extract_ids($element['#entity_type'], $element['#entity']);
 | 
			
		||||
  if (!$id) {
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  $entity_type = 'taxonomy_term';
 | 
			
		||||
  $parent_handler = entity_translation_get_handler($element['#entity_type'], $element['#entity']);
 | 
			
		||||
  $active_langcode = $parent_handler->getActiveLanguage();
 | 
			
		||||
  $translations = $parent_handler->getTranslations();
 | 
			
		||||
  $entity_langcode = isset($translations->original) ? $translations->original : LANGUAGE_NONE;
 | 
			
		||||
  $instance = field_info_instance($element['#entity_type'], $field['field_name'], $bundle);
 | 
			
		||||
 | 
			
		||||
  // We need to make sure that we are not dealing with a translation form.
 | 
			
		||||
  // However checking the active language is not enough, because the user may
 | 
			
		||||
  // have changed the entity language.
 | 
			
		||||
  return
 | 
			
		||||
    (isset($form_state['entity_translation']['is_translation']) ?
 | 
			
		||||
      $form_state['entity_translation']['is_translation'] : ($active_langcode != $entity_langcode)) &&
 | 
			
		||||
    !empty($instance['settings']['entity_translation_taxonomy_autocomplete_translate']) &&
 | 
			
		||||
    (user_access('translate any entity') || user_access("translate $entity_type entities"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_field_widget_WIDGET_TYPE_form_alter().
 | 
			
		||||
 *
 | 
			
		||||
 * {@inheritdoc}
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_field_widget_taxonomy_autocomplete_form_alter(&$element, &$form_state, $context) {
 | 
			
		||||
  // The autocomplete widget is also displayed in the field configuration form,
 | 
			
		||||
  // in which case we do not need to perform any alteration. To preserve BC, by
 | 
			
		||||
  // default we enable our taxonomy autocomplete override only on new sites.
 | 
			
		||||
  if (!isset($element['#entity']) || !variable_get('entity_translation_taxonomy_autocomplete', FALSE)) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // We will need to translate term names, if Title is enabled and configured
 | 
			
		||||
  // for this vocabulary.
 | 
			
		||||
  $entity_type = 'taxonomy_term';
 | 
			
		||||
  $field = field_widget_field($element, $form_state);
 | 
			
		||||
  $bundle = !empty($field['settings']['allowed_values'][0]['vocabulary']) ? $field['settings']['allowed_values'][0]['vocabulary'] : NULL;
 | 
			
		||||
  if ($bundle && entity_translation_enabled($entity_type, $bundle)) {
 | 
			
		||||
    $parent_handler = entity_translation_get_handler($element['#entity_type'], $element['#entity']);
 | 
			
		||||
    $langcode = $parent_handler->getActiveLanguage();
 | 
			
		||||
    $terms = array_values(_entity_translation_taxonomy_autocomplete_widget_get_terms($element));
 | 
			
		||||
 | 
			
		||||
    // If we are using the regular autocomplete behavior also in translation
 | 
			
		||||
    // forms, we need to set our custom callback.
 | 
			
		||||
    if (!_entity_translation_taxonomy_autocomplete_translation_enabled($element, $form_state)) {
 | 
			
		||||
      $element['#autocomplete_path'] = 'entity_translation/' . $entity_type . '/autocomplete/' . $langcode . '/' . $element['#field_name'];
 | 
			
		||||
      $translations = $parent_handler->getTranslations();
 | 
			
		||||
      if (isset($translations->original) && $translations->original != $langcode) {
 | 
			
		||||
        $labels = array();
 | 
			
		||||
        foreach ($terms as $delta => $term) {
 | 
			
		||||
          $labels[] = _entity_translation_taxonomy_label($term, $langcode);
 | 
			
		||||
        }
 | 
			
		||||
        $element['#default_value'] = implode(', ', $labels);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // Otherwise we just provide the in-place translation widget.
 | 
			
		||||
    else {
 | 
			
		||||
      $element['#type'] = 'fieldset';
 | 
			
		||||
      $element['#description'] = t('Enter one translation for each term');
 | 
			
		||||
      $element['#access'] = (bool) $terms;
 | 
			
		||||
      foreach ($terms as $delta => $term) {
 | 
			
		||||
        $element[$delta] = array(
 | 
			
		||||
          '#type' => 'textfield',
 | 
			
		||||
          '#default_value' => _entity_translation_taxonomy_label($term, $langcode),
 | 
			
		||||
          '#required' => TRUE,
 | 
			
		||||
          '#tid' => $term->tid,
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
      $element['#process'][] = 'entity_translation_taxonomy_autocomplete_process';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // The native term save logic is performed at widget validation level, so we
 | 
			
		||||
    // just replace the validation handler to provide our logic instead.
 | 
			
		||||
    $element['#element_validate'] = array_values(array_diff($element['#element_validate'], array('taxonomy_autocomplete_validate')));
 | 
			
		||||
    $element['#element_validate'][] = 'entity_translation_taxonomy_autocomplete_validate';
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns the terms referenced by the taxonomy autocomplete widget field.
 | 
			
		||||
 *
 | 
			
		||||
 * @param array $element
 | 
			
		||||
 *   The taxonomy autocomplete form element.
 | 
			
		||||
 *
 | 
			
		||||
 * @return object[]
 | 
			
		||||
 *   An associative array of taxonomy term object keyed by their identifiers.
 | 
			
		||||
 */
 | 
			
		||||
function _entity_translation_taxonomy_autocomplete_widget_get_terms($element) {
 | 
			
		||||
  $items = isset($element['#entity']->{$element['#field_name']}[$element['#language']]) ?
 | 
			
		||||
    $element['#entity']->{$element['#field_name']}[$element['#language']] : array();
 | 
			
		||||
  $tids = array_map(function ($item) { return $item['tid']; }, $items);
 | 
			
		||||
  return taxonomy_term_load_multiple($tids);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Process callback for the ET taxonomy autocomplete widget.
 | 
			
		||||
 *
 | 
			
		||||
 * {@inheritdoc}
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_taxonomy_autocomplete_process($element) {
 | 
			
		||||
  // The in-place translation widget makes sense only for untranslatable field,
 | 
			
		||||
  // which may have the "(all languages)" label suffix. In this case it would be
 | 
			
		||||
  // confusing so we need to revert that.
 | 
			
		||||
  $instance = field_info_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']);
 | 
			
		||||
  $element['#title'] = check_plain($instance['label']);
 | 
			
		||||
  return $element;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Entity translation taxonomy autocomplete callback.
 | 
			
		||||
 *
 | 
			
		||||
 * @param string $langcode
 | 
			
		||||
 *   The input language.
 | 
			
		||||
 * @param string $field_name
 | 
			
		||||
 *   The name of the term reference field.
 | 
			
		||||
 * @param string $tags_typed
 | 
			
		||||
 *   (optional) A comma-separated list of term names entered in the
 | 
			
		||||
 *   autocomplete form element. Only the last term is used for autocompletion.
 | 
			
		||||
 *   Defaults to an empty string.
 | 
			
		||||
 *
 | 
			
		||||
 * @see taxonomy_autocomplete()
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_taxonomy_term_autocomplete($langcode = NULL, $field_name = '', $tags_typed = '') {
 | 
			
		||||
  // If the request has a '/' in the search text, then the menu system will have
 | 
			
		||||
  // split it into multiple arguments, recover the intended $tags_typed.
 | 
			
		||||
  $args = func_get_args();
 | 
			
		||||
  // Shift off the $langcode and $field_name arguments.
 | 
			
		||||
  array_shift($args);
 | 
			
		||||
  array_shift($args);
 | 
			
		||||
  $tags_typed = implode('/', $args);
 | 
			
		||||
 | 
			
		||||
  // Make sure the field exists and is a taxonomy field.
 | 
			
		||||
  if (!($field = field_info_field($field_name)) || $field['type'] !== 'taxonomy_term_reference') {
 | 
			
		||||
    // Error string. The JavaScript handler will realize this is not JSON and
 | 
			
		||||
    // will display it as debugging information.
 | 
			
		||||
    print t('Taxonomy field @field_name not found.', array('@field_name' => $field_name));
 | 
			
		||||
    exit;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // The user enters a comma-separated list of tags. We only autocomplete the
 | 
			
		||||
  // last tag.
 | 
			
		||||
  $tags_typed = drupal_explode_tags($tags_typed);
 | 
			
		||||
  $tag_last = drupal_strtolower(array_pop($tags_typed));
 | 
			
		||||
 | 
			
		||||
  $term_matches = array();
 | 
			
		||||
  if ($tag_last != '') {
 | 
			
		||||
    if (!isset($langcode) || $langcode == LANGUAGE_NONE) {
 | 
			
		||||
      $langcode = $GLOBALS['language_content']->language;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Part of the criteria for the query come from the field's own settings.
 | 
			
		||||
    $vocabulary = _entity_translation_taxonomy_reference_get_vocabulary($field);
 | 
			
		||||
 | 
			
		||||
    $entity_type = 'taxonomy_term';
 | 
			
		||||
    $query = new EntityFieldQuery();
 | 
			
		||||
    $query->addTag('taxonomy_term_access');
 | 
			
		||||
    $query->entityCondition('entity_type', $entity_type);
 | 
			
		||||
 | 
			
		||||
    // If the Title module is enabled and the taxonomy term name is replaced for
 | 
			
		||||
    // the current bundle, we can look for translated names, otherwise we fall
 | 
			
		||||
    // back to the regular name property.
 | 
			
		||||
    if (module_invoke('title', 'field_replacement_enabled', $entity_type, $vocabulary->machine_name, 'name')) {
 | 
			
		||||
      $name_field = 'name_field';
 | 
			
		||||
      $language_group = 0;
 | 
			
		||||
      // Do not select already entered terms.
 | 
			
		||||
      $column = 'value';
 | 
			
		||||
      if (!empty($tags_typed)) {
 | 
			
		||||
        $query->fieldCondition($name_field, $column, $tags_typed, 'NOT IN', NULL, $language_group);
 | 
			
		||||
      }
 | 
			
		||||
      $query->fieldCondition($name_field, $column, $tag_last, 'CONTAINS', NULL, $language_group);
 | 
			
		||||
      $query->fieldLanguageCondition($name_field, array($langcode, LANGUAGE_NONE), NULL, NULL, $language_group);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      $name_field = 'name';
 | 
			
		||||
      // Do not select already entered terms.
 | 
			
		||||
      if (!empty($tags_typed)) {
 | 
			
		||||
        $query->propertyCondition($name_field, $tags_typed, 'NOT IN');
 | 
			
		||||
      }
 | 
			
		||||
      $query->propertyCondition($name_field, $tag_last, 'CONTAINS');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Select rows that match by term name.
 | 
			
		||||
    $query->propertyCondition('vid', $vocabulary->vid);
 | 
			
		||||
    $query->range(0, 10);
 | 
			
		||||
    $result = $query->execute();
 | 
			
		||||
 | 
			
		||||
    // Populate the results array.
 | 
			
		||||
    $prefix = count($tags_typed) ? drupal_implode_tags($tags_typed) . ', ' : '';
 | 
			
		||||
    $terms = !empty($result[$entity_type]) ? taxonomy_term_load_multiple(array_keys($result[$entity_type])) : array();
 | 
			
		||||
    foreach ($terms as $tid => $term) {
 | 
			
		||||
      $name = _entity_translation_taxonomy_label($term, $langcode);
 | 
			
		||||
      $n = $name;
 | 
			
		||||
      // Term names containing commas or quotes must be wrapped in quotes.
 | 
			
		||||
      if (strpos($name, ',') !== FALSE || strpos($name, '"') !== FALSE) {
 | 
			
		||||
        $n = '"' . str_replace('"', '""', $name) . '"';
 | 
			
		||||
      }
 | 
			
		||||
      $term_matches[$prefix . $n] = check_plain($name);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  drupal_json_output($term_matches);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns the vocabulary enabled for the specified taxonomy reference field.
 | 
			
		||||
 *
 | 
			
		||||
 * @param array $field
 | 
			
		||||
 *   A field definition.
 | 
			
		||||
 *
 | 
			
		||||
 * @return object|null
 | 
			
		||||
 *   A vocabulary object or NULL if none is found.
 | 
			
		||||
 */
 | 
			
		||||
function _entity_translation_taxonomy_reference_get_vocabulary($field) {
 | 
			
		||||
  $vocabulary = NULL;
 | 
			
		||||
  if (!empty($field['settings']['allowed_values'])) {
 | 
			
		||||
    $vids = array();
 | 
			
		||||
    $vocabularies = taxonomy_vocabulary_get_names();
 | 
			
		||||
    foreach ($field['settings']['allowed_values'] as $tree) {
 | 
			
		||||
      $vids[] = $vocabularies[$tree['vocabulary']]->vid;
 | 
			
		||||
    }
 | 
			
		||||
    $vocabulary = taxonomy_vocabulary_load(reset($vids));
 | 
			
		||||
  }
 | 
			
		||||
  return $vocabulary;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Form element validate handler for taxonomy term autocomplete element.
 | 
			
		||||
 *
 | 
			
		||||
 * {@inheritdoc}
 | 
			
		||||
 *
 | 
			
		||||
 * @see taxonomy_autocomplete_validate()
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_taxonomy_autocomplete_validate($element, &$form_state) {
 | 
			
		||||
  $value = array();
 | 
			
		||||
  list($id) = entity_extract_ids($element['#entity_type'], $element['#entity']);
 | 
			
		||||
  $is_new = !isset($id);
 | 
			
		||||
 | 
			
		||||
  // This is the language of the parent entity, that we will be applying to new
 | 
			
		||||
  // terms.
 | 
			
		||||
  $parent_handler = entity_translation_get_handler($element['#entity_type'], $element['#entity']);
 | 
			
		||||
  $langcode = !empty($form_state['entity_translation']['form_langcode']) ?
 | 
			
		||||
    $form_state['entity_translation']['form_langcode'] : $parent_handler->getActiveLanguage();
 | 
			
		||||
 | 
			
		||||
  // Handle in-place translation.
 | 
			
		||||
  if (_entity_translation_taxonomy_autocomplete_translation_enabled($element, $form_state)) {
 | 
			
		||||
    // The referenced terms cannot change, so we just need to collect their term
 | 
			
		||||
    // identifiers. We also build a map of the corresponding deltas for later
 | 
			
		||||
    // use.
 | 
			
		||||
    $deltas = array();
 | 
			
		||||
    foreach (element_children($element) as $delta) {
 | 
			
		||||
      $tid = $element[$delta]['#tid'];
 | 
			
		||||
      $deltas[$tid] = $delta;
 | 
			
		||||
      $value[$delta]['tid'] = $tid;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Save term translations.
 | 
			
		||||
    $entity_type = 'taxonomy_term';
 | 
			
		||||
    $name_field = 'name_field';
 | 
			
		||||
    $source_langcode = $parent_handler->getSourceLanguage();
 | 
			
		||||
    // This is a validation handler, so we must defer the actual save to the
 | 
			
		||||
    // submit phase.
 | 
			
		||||
    $terms_to_save = &$form_state['entity_translation']['taxonomy_autocomplete'][$element['#entity_type']][$id][$element['#field_name']];
 | 
			
		||||
    foreach (taxonomy_term_load_multiple(array_keys($deltas)) as $term) {
 | 
			
		||||
      // This is also the right context to perform validation.
 | 
			
		||||
      $term_translation = $element[$deltas[$term->tid]]['#value'];
 | 
			
		||||
      if (!$term_translation) {
 | 
			
		||||
        $instance = field_info_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']);
 | 
			
		||||
        drupal_set_message(t('The translations for %field_label cannot be empty.', array('%field_label' => $instance['label'])), 'error', FALSE);
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      $handler = entity_translation_get_handler($entity_type, $term);
 | 
			
		||||
      $translations = $handler->getTranslations();
 | 
			
		||||
      $term_langcode = $handler->getLanguage();
 | 
			
		||||
      $typed_langcode = $term_langcode != LANGUAGE_NONE ? $langcode : $term_langcode;
 | 
			
		||||
 | 
			
		||||
      // Create a new translation in the active language, if it is missing.
 | 
			
		||||
      if (!isset($translations->data[$typed_langcode]) && $typed_langcode != LANGUAGE_NONE) {
 | 
			
		||||
        $translation = array(
 | 
			
		||||
          'language' => $typed_langcode,
 | 
			
		||||
          'source' => $source_langcode,
 | 
			
		||||
          'uid' => $GLOBALS['user']->uid,
 | 
			
		||||
          'status' => 1,
 | 
			
		||||
          'created' => REQUEST_TIME,
 | 
			
		||||
          'changed' => REQUEST_TIME,
 | 
			
		||||
        );
 | 
			
		||||
        $translation_values = array(
 | 
			
		||||
          $name_field => array($typed_langcode => array(array('value' => $term_translation))),
 | 
			
		||||
        );
 | 
			
		||||
        $handler->setTranslation($translation, $translation_values);
 | 
			
		||||
        $terms_to_save[] = $term;
 | 
			
		||||
      }
 | 
			
		||||
      // Otherwise we just update the existing translation, if it has changed.
 | 
			
		||||
      // If the term is language-neutral, we just update its main value. This is
 | 
			
		||||
      // expected to happen normally, but could when referencing existing terms.
 | 
			
		||||
      elseif ($term_translation != _entity_translation_taxonomy_label($term, $typed_langcode)) {
 | 
			
		||||
        $term->{$name_field}[$typed_langcode][0]['value'] = $term_translation;
 | 
			
		||||
        $terms_to_save[] = $term;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // Autocomplete widgets do not send their tids in the form, so we must detect
 | 
			
		||||
  // them here and process them independently.
 | 
			
		||||
  elseif ($tags = $element['#value']) {
 | 
			
		||||
    $entity_type = 'taxonomy_term';
 | 
			
		||||
    $field = field_widget_field($element, $form_state);
 | 
			
		||||
    $vocabulary = _entity_translation_taxonomy_reference_get_vocabulary($field);
 | 
			
		||||
    $typed_tags = drupal_explode_tags($tags);
 | 
			
		||||
 | 
			
		||||
    // Collect existing terms by name.
 | 
			
		||||
    $existing_terms = array();
 | 
			
		||||
    foreach (_entity_translation_taxonomy_autocomplete_widget_get_terms($element) as $term) {
 | 
			
		||||
      $name = _entity_translation_taxonomy_label($term, $langcode);
 | 
			
		||||
      $existing_terms[$name] = $term;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Select terms that match by the (translated) name.
 | 
			
		||||
    $query = new EntityFieldQuery();
 | 
			
		||||
    $query->addTag('taxonomy_term_access');
 | 
			
		||||
    $query->entityCondition('entity_type', $entity_type);
 | 
			
		||||
    $query->propertyCondition('vid', $vocabulary->vid);
 | 
			
		||||
    if ($langcode != LANGUAGE_NONE && module_invoke('title', 'field_replacement_enabled', $entity_type, $vocabulary->machine_name, 'name')) {
 | 
			
		||||
      $language_group = 0;
 | 
			
		||||
      // Do not select already entered terms.
 | 
			
		||||
      $name_field = 'name_field';
 | 
			
		||||
      $column = 'value';
 | 
			
		||||
      $query->fieldCondition($name_field, $column, $typed_tags, NULL, NULL, $language_group);
 | 
			
		||||
      // When we are creating a new entity, we cannot filter by active language,
 | 
			
		||||
      // as that may have not be applied to the autocomplete query.
 | 
			
		||||
      if (!$is_new) {
 | 
			
		||||
        $query->fieldLanguageCondition($name_field, array($langcode, LANGUAGE_NONE), NULL, NULL, $language_group);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      $query->propertyCondition('name', $typed_tags);
 | 
			
		||||
    }
 | 
			
		||||
    $result = $query->execute();
 | 
			
		||||
 | 
			
		||||
    // When we are creating a new entity, the language used for the autocomplete
 | 
			
		||||
    // query is the current content language, so we should use that to update
 | 
			
		||||
    // the map of existing terms.
 | 
			
		||||
    if (!empty($result[$entity_type])) {
 | 
			
		||||
      $typed_langcode = !$is_new ? $langcode : $GLOBALS['language_content']->language;
 | 
			
		||||
      foreach (taxonomy_term_load_multiple(array_keys($result[$entity_type])) as $term) {
 | 
			
		||||
        $name = _entity_translation_taxonomy_label($term, $typed_langcode);
 | 
			
		||||
        $existing_terms[$name] = $term;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Now collect the identifiers for the various terms and update the taxonomy
 | 
			
		||||
    // reference field values.
 | 
			
		||||
    foreach ($typed_tags as $delta => $typed_tag) {
 | 
			
		||||
      // See if the term exists in the chosen vocabulary and return the tid.
 | 
			
		||||
      // Otherwise create a new 'autocreate' term for insert/update.
 | 
			
		||||
      if (isset($existing_terms[$typed_tag])) {
 | 
			
		||||
        $term = $existing_terms[$typed_tag];
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        $term = (object) array(
 | 
			
		||||
          'tid' => 'autocreate',
 | 
			
		||||
          'vid' => $vocabulary->vid,
 | 
			
		||||
          'name' => $typed_tag,
 | 
			
		||||
          'vocabulary_machine_name' => $vocabulary->machine_name,
 | 
			
		||||
        );
 | 
			
		||||
        $handler = entity_translation_get_handler($entity_type, $term);
 | 
			
		||||
        $handler->setOriginalLanguage($langcode);
 | 
			
		||||
        $handler->initTranslations();
 | 
			
		||||
      }
 | 
			
		||||
      $value[] = (array) $term;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  form_set_value($element, $value, $form_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Term-specific implementation of hook_field_attach_submit().
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_taxonomy_term_field_attach_submit($entity_type, $entity, $form, &$form_state) {
 | 
			
		||||
  // Finally save in-place translations
 | 
			
		||||
  if (!empty($form_state['entity_translation']['taxonomy_autocomplete'])) {
 | 
			
		||||
    foreach ($form_state['entity_translation']['taxonomy_autocomplete'] as $entity_type => $entity_type_data) {
 | 
			
		||||
      foreach ($entity_type_data as $id => $field_name_data) {
 | 
			
		||||
        foreach ($field_name_data as $field_name => $term_data) {
 | 
			
		||||
          if (!is_array($term_data)) {
 | 
			
		||||
            continue;
 | 
			
		||||
          }
 | 
			
		||||
          foreach ($term_data as $term) {
 | 
			
		||||
            entity_translation_entity_save('taxonomy_term', $term);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,9 +7,8 @@ dependencies[] = i18n
 | 
			
		||||
dependencies[] = i18n_menu
 | 
			
		||||
files[] = entity_translation_i18n_menu.test
 | 
			
		||||
 | 
			
		||||
; Information added by Drupal.org packaging script on 2016-09-28
 | 
			
		||||
version = "7.x-1.0-beta5+15-dev"
 | 
			
		||||
; Information added by Drupal.org packaging script on 2019-01-20
 | 
			
		||||
version = "7.x-1.0+5-dev"
 | 
			
		||||
core = "7.x"
 | 
			
		||||
project = "entity_translation"
 | 
			
		||||
datestamp = "1475057941"
 | 
			
		||||
 | 
			
		||||
datestamp = "1548022384"
 | 
			
		||||
 
 | 
			
		||||
@@ -164,7 +164,7 @@ function entity_translation_i18n_menu_form(&$form, &$form_state) {
 | 
			
		||||
      $default = isset($source_menu['language']) && $source_menu['language'] != LANGUAGE_NONE;
 | 
			
		||||
      $languages = language_list();
 | 
			
		||||
      $handler = entity_translation_entity_form_get_handler($form, $form_state);
 | 
			
		||||
      $langcode = $handler->getFormLanguage();
 | 
			
		||||
      $langcode = $handler->getActiveLanguage();
 | 
			
		||||
      $language_name = isset($languages[$langcode]) ? t($languages[$langcode]->name) : t('current');
 | 
			
		||||
 | 
			
		||||
      $form['menu']['#multilingual'] = TRUE;
 | 
			
		||||
 
 | 
			
		||||
@@ -125,23 +125,36 @@ class EntityTranslationMenuTranslationTestCase extends EntityTranslationTestCase
 | 
			
		||||
    $this->assertText($link_title, 'New menu link title found: ' . $link_title);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Asserts a link with a given label and title is found in the page.
 | 
			
		||||
   */
 | 
			
		||||
  function assertLinkWithTitleAttribute($label, $title) {
 | 
			
		||||
    $links = $this->xpath('//a[normalize-space(text())=:label and normalize-space(@title)=:title]', array(
 | 
			
		||||
      ':label' => $label,
 | 
			
		||||
      ':title' => $title,
 | 
			
		||||
    ));
 | 
			
		||||
    $this->assert(isset($links[0]));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Test if menu localization works.
 | 
			
		||||
   */
 | 
			
		||||
  function testMenuLocalization() {
 | 
			
		||||
    // Create Basic page in English.
 | 
			
		||||
    $link_title_en = $this->randomName();
 | 
			
		||||
    $node = $this->createPage($link_title_en, NULL, 'en');
 | 
			
		||||
    $link_description_en = $this->randomName() . ' & htmlentity';
 | 
			
		||||
    $node = $this->createPage($link_title_en, $link_description_en, 'en');
 | 
			
		||||
 | 
			
		||||
    // Submit translation in Spanish.
 | 
			
		||||
    $link_title_es = $this->randomName();
 | 
			
		||||
    $node_translation = $this->createTranslation($node, $link_title_es, NULL, 'es');
 | 
			
		||||
    $link_description_es = $this->randomName() . ' & htmlentity';
 | 
			
		||||
    $node_translation = $this->createTranslation($node, $link_title_es, $link_description_es, 'es');
 | 
			
		||||
 | 
			
		||||
    // Check menu links in both languages.
 | 
			
		||||
    $this->get('en', '<front>');
 | 
			
		||||
    $this->assertText($link_title_en);
 | 
			
		||||
    $this->assertLinkWithTitleAttribute($link_title_en, $link_description_en);
 | 
			
		||||
    $this->get('es', '<front>');
 | 
			
		||||
    $this->assertText($link_title_es);
 | 
			
		||||
    $this->assertLinkWithTitleAttribute($link_title_es, $link_description_es);
 | 
			
		||||
 | 
			
		||||
    // Edit English menu link.
 | 
			
		||||
    $link_title_en2 = $this->randomName();
 | 
			
		||||
@@ -149,15 +162,19 @@ class EntityTranslationMenuTranslationTestCase extends EntityTranslationTestCase
 | 
			
		||||
 | 
			
		||||
    // Check that Spanish menu link has not changed.
 | 
			
		||||
    $this->get('es', '<front>');
 | 
			
		||||
    $this->assertText($link_title_es);
 | 
			
		||||
    $this->assertLinkWithTitleAttribute($link_title_es, $link_description_es);
 | 
			
		||||
 | 
			
		||||
    // Edit Spanish menu link.
 | 
			
		||||
    $link_title_es2 = $this->randomName();
 | 
			
		||||
    $this->editPage($node, $link_title_es, $link_title_es2, 'es');
 | 
			
		||||
 | 
			
		||||
    // Check that English menu link has not changed.
 | 
			
		||||
    // Check that English menu link has changed.
 | 
			
		||||
    $this->get('en', '<front>');
 | 
			
		||||
    $this->assertText($link_title_en2);
 | 
			
		||||
    $this->assertLinkWithTitleAttribute($link_title_en2, $link_description_en);
 | 
			
		||||
 | 
			
		||||
    // Check that Spanish menu link has changed.
 | 
			
		||||
    $this->get('es', '<front>');
 | 
			
		||||
    $this->assertLinkWithTitleAttribute($link_title_es2, $link_description_es);
 | 
			
		||||
 | 
			
		||||
    // Delete Spanish translation and check that the respective menu item has
 | 
			
		||||
    // been deleted as well.
 | 
			
		||||
 
 | 
			
		||||
@@ -34,8 +34,8 @@ function entity_translation_upgrade_start($types) {
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_upgrade_end($success, $results, $operations, $elapsed) {
 | 
			
		||||
  if (!empty($results)) {
 | 
			
		||||
    $message = format_plural($results, '1 node translation successfully upgraded.', '@count node translations successfully upgraded.');
 | 
			
		||||
    watchdog('entity translation upgrade', '@count node translations successfully upgraded.', array('@count' => $results), WATCHDOG_INFO);
 | 
			
		||||
    $message = format_plural($results['total'], '1 node translation successfully upgraded.', '@count node translations successfully upgraded.');
 | 
			
		||||
    watchdog('entity translation upgrade', '@count node translations successfully upgraded.', array('@count' => $results['total']), WATCHDOG_INFO);
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    $message = t('No node translation available for the upgrade.');
 | 
			
		||||
@@ -91,6 +91,10 @@ function entity_translation_upgrade_do($types, &$context) {
 | 
			
		||||
      $node = $nodes[$nid];
 | 
			
		||||
      $original = $nodes[$node->tnid];
 | 
			
		||||
      $handler = entity_translation_get_handler('node', $original);
 | 
			
		||||
      // Instantiate the data and original properties of the translations.
 | 
			
		||||
      if (empty($handler->getTranslations()->data)) {
 | 
			
		||||
        $handler->initTranslations();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (!isset($instances[$node->type])) {
 | 
			
		||||
        $instances[$node->type] = field_info_instances('node', $node->type);
 | 
			
		||||
@@ -185,7 +189,7 @@ function entity_translation_upgrade_do($types, &$context) {
 | 
			
		||||
    $context['finished'] = $context['sandbox']['count'] / $context['sandbox']['total'];
 | 
			
		||||
 | 
			
		||||
    if ($context['finished'] >= 1) {
 | 
			
		||||
      $context['results'] = $context['sandbox']['total'];
 | 
			
		||||
      $context['results']['total'] = $context['sandbox']['total'];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,117 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_drush_command().
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_upgrade_drush_command() {
 | 
			
		||||
  $items = array();
 | 
			
		||||
 | 
			
		||||
  $items['entity-translation-upgrade'] = array(
 | 
			
		||||
    'description' => "Upgrades all nodes of the specified content type from Content Translation to Entity Translation.",
 | 
			
		||||
    'arguments' => array(
 | 
			
		||||
      'content_type' => 'Content type of nodes to be upgraded.',
 | 
			
		||||
    ),
 | 
			
		||||
    'examples' => array(
 | 
			
		||||
      'drush entity-translation-upgrade article' => 'Upgrades all nodes of content type "article" from Content Translation to Entity Translation.',
 | 
			
		||||
    ),
 | 
			
		||||
    'aliases' => array('etu'),
 | 
			
		||||
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return $items;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_drush_help().
 | 
			
		||||
 *
 | 
			
		||||
 * @param
 | 
			
		||||
 *   A string with the help section
 | 
			
		||||
 *
 | 
			
		||||
 * @return
 | 
			
		||||
 *   A string with the help text for the entity-translation-upgrade command
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_upgrade_drush_help($section) {
 | 
			
		||||
  switch ($section) {
 | 
			
		||||
    case 'drush:entity-translation-upgrade':
 | 
			
		||||
      return dt("Brief help for Drush command entity-translation-upgrade.");
 | 
			
		||||
 | 
			
		||||
    case 'meta:entity_translation_upgrade:title':
 | 
			
		||||
      return dt("Entity Translation Upgrade commands");
 | 
			
		||||
 | 
			
		||||
    case 'meta:entity_translation_upgrade:summary':
 | 
			
		||||
      return dt("Upgrading nodes to Entity Translation.");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements drush_hook_COMMAND().
 | 
			
		||||
 *
 | 
			
		||||
 * @param
 | 
			
		||||
 *   The content type of which the nodes shall be upgraded
 | 
			
		||||
 *
 | 
			
		||||
 * Runs the batch upgrading nodes of the specified content_type to Entity
 | 
			
		||||
 * Translation. Lets user choose content type from a list, if argument has
 | 
			
		||||
 * not been provided.
 | 
			
		||||
 */
 | 
			
		||||
function drush_entity_translation_upgrade($content_type = "") {
 | 
			
		||||
  // Get all installed content types.
 | 
			
		||||
  $available_types = array();
 | 
			
		||||
  $available_types_chose = array();
 | 
			
		||||
  $available_types_str = '';
 | 
			
		||||
  foreach (node_type_get_types() as $type) {
 | 
			
		||||
    $available_types[$type->type] = $type->type;
 | 
			
		||||
    $available_types_chose[$type->type] = $type->name;
 | 
			
		||||
    if (strlen($available_types_str) > 0) {
 | 
			
		||||
      $available_types_str .= ', ';
 | 
			
		||||
    }
 | 
			
		||||
    $available_types_str .= $type->type;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If argument content_type is empty, prompt user for content type.
 | 
			
		||||
  if (!$content_type) {
 | 
			
		||||
    $content_type = drush_choice($available_types_chose, dt('Choose the content type of the nodes to be upgraded to Entity Translation:'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Do content type argument checks.
 | 
			
		||||
  if (!$content_type) {
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  }
 | 
			
		||||
  if (strlen($available_types_str) == 0) {
 | 
			
		||||
    return drush_set_error(dt('Entity Translation Upgrade cannot run as no content type has been installed.'));
 | 
			
		||||
  }
 | 
			
		||||
  if (!in_array($content_type, $available_types)) {
 | 
			
		||||
    return drush_set_error(dt('"@content_type" is not a valid content type machine name. Please use one of these installed content types as argument: @available_types_str.', array('@content_type' => $content_type, '@available_types_str' => $available_types_str)));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Start batch to upgrade nodes of the specified content type.
 | 
			
		||||
  $types = array($content_type => $content_type);
 | 
			
		||||
  $batch = array(
 | 
			
		||||
    'operations' => array(
 | 
			
		||||
      array('entity_translation_upgrade_do', array($types)),
 | 
			
		||||
      array('entity_translation_upgrade_complete', array()),
 | 
			
		||||
    ),
 | 
			
		||||
    'finished' => 'entity_translation_upgrade_drush_end',
 | 
			
		||||
    'file' => drupal_get_path('module', 'entity_translation_upgrade') . '/entity_translation_upgrade.admin.inc',
 | 
			
		||||
    'progressive' => FALSE,
 | 
			
		||||
  );
 | 
			
		||||
  batch_set($batch);
 | 
			
		||||
  drush_backend_batch_process();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This is the 'finished' batch callback, drush version.
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_upgrade_drush_end($success, $results, $operations, $elapsed) {
 | 
			
		||||
  // Print result messages.
 | 
			
		||||
  if (!empty($results)) {
 | 
			
		||||
    $message = format_plural($results['total'], '1 node translation successfully upgraded.', '@count node translations successfully upgraded.');
 | 
			
		||||
    $severity = 'ok';
 | 
			
		||||
    watchdog('Entity Translation upgrade', '@count node translations successfully upgraded.', array('@count' => $results['total']), WATCHDOG_INFO);
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    $message = t('No node translation available for the upgrade.');
 | 
			
		||||
    $severity = 'warning';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  drush_log($message, $severity);
 | 
			
		||||
}
 | 
			
		||||
@@ -3,10 +3,10 @@ description = Provides an upgrade path from node-based translation to field-base
 | 
			
		||||
package = Multilingual - Entity Translation
 | 
			
		||||
core = 7.x
 | 
			
		||||
dependencies[] = entity_translation
 | 
			
		||||
files[] = entity_translation_upgrade.test
 | 
			
		||||
 | 
			
		||||
; Information added by Drupal.org packaging script on 2016-09-28
 | 
			
		||||
version = "7.x-1.0-beta5+15-dev"
 | 
			
		||||
; Information added by Drupal.org packaging script on 2019-01-20
 | 
			
		||||
version = "7.x-1.0+5-dev"
 | 
			
		||||
core = "7.x"
 | 
			
		||||
project = "entity_translation"
 | 
			
		||||
datestamp = "1475057941"
 | 
			
		||||
 | 
			
		||||
datestamp = "1548022384"
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,163 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Tests for Entity Translation module.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests for the upgrade translation process.
 | 
			
		||||
 */
 | 
			
		||||
class EntityTranslationUpgradeTestCase extends EntityTranslationTestCase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Return the test information.
 | 
			
		||||
   */
 | 
			
		||||
  public static function getInfo() {
 | 
			
		||||
    return array(
 | 
			
		||||
      'name' => 'Translation upgrade',
 | 
			
		||||
      'description' => 'Tests for the upgrade from Content Translation to Entity Translation.',
 | 
			
		||||
      'group' => 'Entity translation',
 | 
			
		||||
      'dependencies' => array(),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function setUp() {
 | 
			
		||||
    parent::setUp('locale', 'translation', 'translation_test', 'entity_translation', 'entity_translation_upgrade');
 | 
			
		||||
    $this->getAdminUser(array(
 | 
			
		||||
      'toggle field translatability',
 | 
			
		||||
      'administer entity translation',
 | 
			
		||||
    ));
 | 
			
		||||
    $this->getTranslatorUser(array(
 | 
			
		||||
      'translate content',
 | 
			
		||||
    ));
 | 
			
		||||
    $this->login($this->getAdminUser());
 | 
			
		||||
    $this->addLanguage('en');
 | 
			
		||||
    $this->addLanguage('es');
 | 
			
		||||
    $this->configureContentTypeForContentTranslation();
 | 
			
		||||
    $this->enableUrlLanguageDetection();
 | 
			
		||||
    $this->login($this->getTranslatorUser());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configure the "Basic page" content type for entity translation tests.
 | 
			
		||||
   */
 | 
			
		||||
  public function configureContentTypeForContentTranslation() {
 | 
			
		||||
    // Configure the "Basic page" content type to use multilingual support with
 | 
			
		||||
    // content translation.
 | 
			
		||||
    $edit = array();
 | 
			
		||||
    $edit['language_content_type'] = TRANSLATION_ENABLED;
 | 
			
		||||
    $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
 | 
			
		||||
    $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), t('Basic page content type has been updated.'));
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Toggle body field's translatability.
 | 
			
		||||
   */
 | 
			
		||||
  public function makeBodyFieldTranslatable() {
 | 
			
		||||
    $edit = array();
 | 
			
		||||
    $this->drupalGet('admin/structure/types/manage/page/fields/body');
 | 
			
		||||
    $this->clickLink('Enable translation');
 | 
			
		||||
    $this->drupalPost(NULL, array(), t('Confirm'));
 | 
			
		||||
    $this->assertRaw(t('Data successfully processed.'), t('Body field have been made translatable.'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @see TranslationTestCase::createPage
 | 
			
		||||
   */
 | 
			
		||||
  function createContentTranslationPage($title, $body, $language = NULL) {
 | 
			
		||||
    $edit = array();
 | 
			
		||||
    $langcode = LANGUAGE_NONE;
 | 
			
		||||
    $edit["title"] = $title;
 | 
			
		||||
    $edit["body[$langcode][0][value]"] = $body;
 | 
			
		||||
    if (!empty($language)) {
 | 
			
		||||
      $edit['language'] = $language;
 | 
			
		||||
    }
 | 
			
		||||
    $this->drupalPost('node/add/page', $edit, t('Save'));
 | 
			
		||||
    $this->assertRaw(t('Basic page %title has been created.', array('%title' => $title)), 'Basic page created.');
 | 
			
		||||
 | 
			
		||||
    // Check to make sure the node was created.
 | 
			
		||||
    $node = $this->drupalGetNodeByTitle($title);
 | 
			
		||||
    $this->assertTrue($node, 'Node found in database.');
 | 
			
		||||
 | 
			
		||||
    return $node;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @see TranslationTestCase::createTranslation
 | 
			
		||||
   */
 | 
			
		||||
  function createContentTranslationTranslation($node, $title, $body, $language) {
 | 
			
		||||
    $this->drupalGet('node/add/page', array('query' => array('translation' => $node->nid, 'target' => $language)));
 | 
			
		||||
 | 
			
		||||
    $langcode = LANGUAGE_NONE;
 | 
			
		||||
    $body_key = "body[$langcode][0][value]";
 | 
			
		||||
    $this->assertFieldByXPath('//input[@id="edit-title"]', $node->title, "Original title value correctly populated.");
 | 
			
		||||
    $this->assertFieldByXPath("//textarea[@name='$body_key']", $node->body[LANGUAGE_NONE][0]['value'], "Original body value correctly populated.");
 | 
			
		||||
 | 
			
		||||
    $edit = array();
 | 
			
		||||
    $edit["title"] = $title;
 | 
			
		||||
    $edit[$body_key] = $body;
 | 
			
		||||
    $this->drupalPost(NULL, $edit, t('Save'));
 | 
			
		||||
    $this->assertRaw(t('Basic page %title has been created.', array('%title' => $title)), 'Translation created.');
 | 
			
		||||
 | 
			
		||||
    // Check to make sure that translation was successful.
 | 
			
		||||
    $translation = $this->drupalGetNodeByTitle($title);
 | 
			
		||||
    $this->assertTrue($translation, 'Node found in database.');
 | 
			
		||||
    $this->assertTrue($translation->tnid == $node->nid, 'Translation set id correctly stored.');
 | 
			
		||||
 | 
			
		||||
    return $translation;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests copying of source node's body value in the add translation form page.
 | 
			
		||||
   */
 | 
			
		||||
  public function testUpgradeContentToEntityTranslation() {
 | 
			
		||||
    // Create Basic page in English.
 | 
			
		||||
    $node_title = $this->randomName();
 | 
			
		||||
    $node_body = $this->randomName();
 | 
			
		||||
    $node = $this->createContentTranslationPage($node_title, $node_body, 'en');
 | 
			
		||||
 | 
			
		||||
    // Submit translation in Spanish.
 | 
			
		||||
    $this->drupalGet('node/' . $node->nid . '/translate');
 | 
			
		||||
    $node_translation_title = $this->randomName();
 | 
			
		||||
    $node_translation_body = $this->randomName();
 | 
			
		||||
    $node_translation = $this->createContentTranslationTranslation($node, $node_translation_title, $node_translation_body, 'es');
 | 
			
		||||
 | 
			
		||||
    // Make Body field translatable before we run the upgrade.
 | 
			
		||||
    $this->login($this->getAdminUser());
 | 
			
		||||
    $this->makeBodyFieldTranslatable();
 | 
			
		||||
 | 
			
		||||
    // Run the upgrade for all Page nodes.
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'types[page]' => 'page',
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('admin/config/regional/entity_translation', $edit, t('Upgrade'));
 | 
			
		||||
 | 
			
		||||
    // Switch to our translator user.
 | 
			
		||||
    $this->login($this->getTranslatorUser());
 | 
			
		||||
 | 
			
		||||
    // Check that the unpublished target node triggers a redirect.
 | 
			
		||||
    $this->drupalGet('node/' . $node_translation->nid);
 | 
			
		||||
    $headers = $this->drupalGetHeaders(TRUE);
 | 
			
		||||
    list(, $status) = explode(' ', $headers[0][':status'], 3);
 | 
			
		||||
    $this->assertEqual($status, 301, 'Expected response code was sent.');
 | 
			
		||||
    $languages = language_list();
 | 
			
		||||
    $this->assertEqual($this->getUrl(), url('node/' . $node->nid, array('absolute' => TRUE, 'language' => $languages['es'])), 'entity_translation_upgrade_redirect() redirected to expected URL.');
 | 
			
		||||
 | 
			
		||||
    // Check that the body is displayed when the active language is English.
 | 
			
		||||
    $this->drupalGet('node/' . $node->nid);
 | 
			
		||||
    $this->assertRaw($node_body, t('Body field displayed correctly in the source language.'));
 | 
			
		||||
 | 
			
		||||
    // Check that the translated body is displayed when the active language is Spanish.
 | 
			
		||||
    $this->drupalGet('es/node/' . $node->nid);
 | 
			
		||||
    $this->assertRaw($node_translation_body, t('Body field displayed correctly in the target language.'));
 | 
			
		||||
 | 
			
		||||
    // Check that the edit forms are initialized correctly in the target language.
 | 
			
		||||
    $this->drupalGet('node/' . $node->nid . '/edit');
 | 
			
		||||
    $this->assertFieldByXPath("//textarea[@name='body[en][0][value]']", $node_body, "Body field correctly instantiated with the value of the source language.");
 | 
			
		||||
    $this->drupalGet('es/node/' . $node->nid . '/edit');
 | 
			
		||||
    $this->assertFieldByXPath("//textarea[@name='body[es][0][value]']", $node_translation_body, "Body field correctly instantiated with the value of the target language.");
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -98,6 +98,62 @@ interface EntityTranslationHandlerInterface {
 | 
			
		||||
   */
 | 
			
		||||
  public function getLanguage();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Sets the active language.
 | 
			
		||||
   *
 | 
			
		||||
   * This is the language that determines which translation should be considered
 | 
			
		||||
   * "active" for the wrapped entity. The "Entity Translation" module uses this
 | 
			
		||||
   * information to implement the UI-based translation workflow. Other modules
 | 
			
		||||
   * can rely on it to implement their own entity translation-related logic.
 | 
			
		||||
   *
 | 
			
		||||
   * This will affect which language is returned by the core "entity_language()"
 | 
			
		||||
   * function.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string $langcode
 | 
			
		||||
   *   The active language code.
 | 
			
		||||
   *
 | 
			
		||||
   * @see entity_language()
 | 
			
		||||
   * @see entity_translation_language()
 | 
			
		||||
   * @see ::getActiveLanguage()
 | 
			
		||||
   */
 | 
			
		||||
  public function setActiveLanguage($langcode);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns the active language.
 | 
			
		||||
   *
 | 
			
		||||
   * @return string
 | 
			
		||||
   *   The active language for the wrapped entity.
 | 
			
		||||
   *
 | 
			
		||||
   * @see ::setActiveLanguage()
 | 
			
		||||
   */
 | 
			
		||||
  public function getActiveLanguage();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Sets the active form language.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string $langcode
 | 
			
		||||
   *   The active form language code.
 | 
			
		||||
   *
 | 
			
		||||
   * @deprecated in 7.x-1.0-beta6, will be removed before 7.x-1.0. Use
 | 
			
		||||
   *   ::setActiveLanguage() instead.
 | 
			
		||||
   *
 | 
			
		||||
   * @see ::setActiveLanguage()
 | 
			
		||||
   */
 | 
			
		||||
  public function setFormLanguage($langcode);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieves the active form language.
 | 
			
		||||
   *
 | 
			
		||||
   * @return string
 | 
			
		||||
   *   The active form language code.
 | 
			
		||||
   *
 | 
			
		||||
   * @deprecated in 7.x-1.0-beta6, will be removed before 7.x-1.0. Use
 | 
			
		||||
   *   ::getActiveLanguage() instead.
 | 
			
		||||
   *
 | 
			
		||||
   * @see ::getActiveLanguage()
 | 
			
		||||
   */
 | 
			
		||||
  public function getFormLanguage();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns the translation object key for the wrapped entity type.
 | 
			
		||||
   */
 | 
			
		||||
@@ -109,7 +165,7 @@ interface EntityTranslationHandlerInterface {
 | 
			
		||||
  public function getDefaultLanguage();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Sets the language of the orginal translation.
 | 
			
		||||
   * Sets the language of the original translation.
 | 
			
		||||
   *
 | 
			
		||||
   * @param $langcode
 | 
			
		||||
   *   The language code of the original content values.
 | 
			
		||||
@@ -272,16 +328,6 @@ interface EntityTranslationHandlerInterface {
 | 
			
		||||
   */
 | 
			
		||||
  public function isAliasEnabled();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Sets the active form language.
 | 
			
		||||
   */
 | 
			
		||||
  public function setFormLanguage($langcode);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieves the active form language.
 | 
			
		||||
   */
 | 
			
		||||
  public function getFormLanguage();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Sets the source language for the translation being created.
 | 
			
		||||
   */
 | 
			
		||||
@@ -364,19 +410,19 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
 | 
			
		||||
   */
 | 
			
		||||
  protected $children = array();
 | 
			
		||||
 | 
			
		||||
  private $entityForm;
 | 
			
		||||
  private $translating;
 | 
			
		||||
  private $outdated;
 | 
			
		||||
  private $formLanguage;
 | 
			
		||||
  private $sourceLanguage;
 | 
			
		||||
  protected $entityForm;
 | 
			
		||||
  protected $translating;
 | 
			
		||||
  protected $outdated;
 | 
			
		||||
  protected $activeLanguage;
 | 
			
		||||
  protected $sourceLanguage;
 | 
			
		||||
 | 
			
		||||
  private $pathScheme;
 | 
			
		||||
  private $pathWildcard;
 | 
			
		||||
  private $basePath;
 | 
			
		||||
  private $editPath;
 | 
			
		||||
  private $translatePath;
 | 
			
		||||
  private $viewPath;
 | 
			
		||||
  private $routerMap;
 | 
			
		||||
  protected $pathScheme;
 | 
			
		||||
  protected $pathWildcard;
 | 
			
		||||
  protected $basePath;
 | 
			
		||||
  protected $editPath;
 | 
			
		||||
  protected $translatePath;
 | 
			
		||||
  protected $viewPath;
 | 
			
		||||
  protected $routerMap;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Initializes an instance of the translation handler.
 | 
			
		||||
@@ -396,7 +442,7 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
 | 
			
		||||
    $this->entityForm = FALSE;
 | 
			
		||||
    $this->translating = FALSE;
 | 
			
		||||
    $this->outdated = FALSE;
 | 
			
		||||
    $this->formLanguage = FALSE;
 | 
			
		||||
    $this->activeLanguage = FALSE;
 | 
			
		||||
    $this->sourceLanguage = FALSE;
 | 
			
		||||
    $this->pathScheme = 'default';
 | 
			
		||||
    $this->routerMap = array();
 | 
			
		||||
@@ -481,7 +527,7 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
 | 
			
		||||
  public function addChild($entity_type, $entity) {
 | 
			
		||||
    if (!empty($this->factory)) {
 | 
			
		||||
      $handler = $this->factory->getHandler($entity_type, $entity);
 | 
			
		||||
      $handler->setFormLanguage($this->getFormLanguage());
 | 
			
		||||
      $handler->setActiveLanguage($this->getActiveLanguage());
 | 
			
		||||
      $handler->setSourceLanguage($this->getSourceLanguage());
 | 
			
		||||
      // Avoid registering more than one child handler for each entity.
 | 
			
		||||
      $hid = $this->factory->getHandlerId($entity_type, $entity);
 | 
			
		||||
@@ -632,6 +678,12 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
 | 
			
		||||
      throw new Exception('Invalid translation language');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // $args will be used later on in a call to notifyChildren(). We need
 | 
			
		||||
    // to call func_get_args() before any modifications to the function's
 | 
			
		||||
    // arguments take place. This is due to changes in PHP 7.0 and onwards.
 | 
			
		||||
    // @see http://php.net/manual/en/function.func-get-args.php#refsect1-function.func-get-args-notes
 | 
			
		||||
    $args = func_get_args();
 | 
			
		||||
 | 
			
		||||
    $translations = $this->getTranslations();
 | 
			
		||||
    $langcode = $translation['language'];
 | 
			
		||||
 | 
			
		||||
@@ -658,13 +710,12 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
 | 
			
		||||
      foreach (field_info_instances($this->entityType, $this->bundle) as $instance) {
 | 
			
		||||
        $field_name = $instance['field_name'];
 | 
			
		||||
        $field = field_info_field($field_name);
 | 
			
		||||
        if ($field['translatable'] && isset($values[$field_name])) {
 | 
			
		||||
        if ($field['translatable'] && isset($values[$field_name][$langcode])) {
 | 
			
		||||
          $this->entity->{$field_name}[$langcode] = $values[$field_name][$langcode];
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $args = func_get_args();
 | 
			
		||||
    $this->notifyChildren(__FUNCTION__, $args);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -803,6 +854,55 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function setActiveLanguage($langcode) {
 | 
			
		||||
    // @todo To fully preserve BC, we proxy the call to the deprecated
 | 
			
		||||
    //   ::setFormLanguage method. This will keep things working even when it
 | 
			
		||||
    //   has been overridden. Inline its implementation here upon removal.
 | 
			
		||||
    $this->setFormLanguage($langcode);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function getActiveLanguage() {
 | 
			
		||||
    // @todo To fully preserve BC, we proxy the call to the deprecated
 | 
			
		||||
    //   ::getFormLanguage method. This will keep things working even when it
 | 
			
		||||
    //   has been overridden. Inline its implementation here upon removal.
 | 
			
		||||
    return $this->getFormLanguage();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function setFormLanguage($langcode) {
 | 
			
		||||
    $this->activeLanguage = $langcode;
 | 
			
		||||
    $args = func_get_args();
 | 
			
		||||
    $this->notifyChildren(__FUNCTION__, $args);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function getFormLanguage() {
 | 
			
		||||
    if (!empty($this->activeLanguage)) {
 | 
			
		||||
      return $this->activeLanguage;
 | 
			
		||||
    }
 | 
			
		||||
    // For new entities the active language should match the default language.
 | 
			
		||||
    // The language stored with the entity itself (for example, $node->language)
 | 
			
		||||
    // may not be reliable since the function creating the entity object will
 | 
			
		||||
    // not know which language "Entity Translation" is configured to create the
 | 
			
		||||
    // entity in.
 | 
			
		||||
    elseif ($this->isNewEntity()) {
 | 
			
		||||
      return $this->getDefaultLanguage();
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      return $this->getLanguage();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @see EntityTranslationHandlerInterface::getLanguageKey()
 | 
			
		||||
   */
 | 
			
		||||
@@ -952,7 +1052,7 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
 | 
			
		||||
    if ($outdated) {
 | 
			
		||||
      $translations = $this->getTranslations();
 | 
			
		||||
      foreach ($translations->data as $langcode => &$translation) {
 | 
			
		||||
        if ($langcode != $this->getFormLanguage()) {
 | 
			
		||||
        if ($langcode != $this->getActiveLanguage()) {
 | 
			
		||||
          $translation['translate'] = 1;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@@ -1097,7 +1197,7 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
 | 
			
		||||
   */
 | 
			
		||||
  public function getSharedFieldsAccess() {
 | 
			
		||||
    $settings = entity_translation_settings($this->entityType, $this->bundle);
 | 
			
		||||
    return ($settings['shared_fields_original_only'] == FALSE || $this->getLanguage() == $this->getFormLanguage()) &&
 | 
			
		||||
    return ($settings['shared_fields_original_only'] == FALSE || $this->getLanguage() == $this->getActiveLanguage()) &&
 | 
			
		||||
      (!entity_translation_workflow_enabled() || user_access('edit translation shared fields') || user_access("edit {$this->entityType} translation shared fields"));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -1108,22 +1208,6 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
 | 
			
		||||
    return !empty($this->entityInfo['translation']['entity_translation']['alias']);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @see EntityTranslationHandlerInterface::setFormLanguage()
 | 
			
		||||
   */
 | 
			
		||||
  public function setFormLanguage($langcode) {
 | 
			
		||||
    $this->formLanguage = $langcode;
 | 
			
		||||
    $args = func_get_args();
 | 
			
		||||
    $this->notifyChildren(__FUNCTION__, $args);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @see EntityTranslationHandlerInterface::getFormLanguage()
 | 
			
		||||
   */
 | 
			
		||||
  public function getFormLanguage() {
 | 
			
		||||
    return !empty($this->formLanguage) ? $this->formLanguage : $this->getLanguage();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @see EntityTranslationHandlerInterface::setSourceLanguage()
 | 
			
		||||
   */
 | 
			
		||||
@@ -1161,7 +1245,7 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
 | 
			
		||||
  public function entityForm(&$form, &$form_state) {
 | 
			
		||||
    $this->entityForm = TRUE;
 | 
			
		||||
    $translations = $this->getTranslations();
 | 
			
		||||
    $form_langcode = $this->getFormLanguage();
 | 
			
		||||
    $form_langcode = $this->getActiveLanguage();
 | 
			
		||||
    $langcode = $this->getLanguage();
 | 
			
		||||
    $is_translation = $this->isTranslationForm();
 | 
			
		||||
    $new_translation = !isset($translations->data[$form_langcode]);
 | 
			
		||||
@@ -1461,7 +1545,7 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
 | 
			
		||||
    $language_key = $this->getLanguageKey();
 | 
			
		||||
    if (isset($form_state['values'][$language_key]) && !$this->isTranslationForm()) {
 | 
			
		||||
      $langcode = $form_state['values'][$language_key];
 | 
			
		||||
      $this->setFormLanguage($langcode);
 | 
			
		||||
      $this->setActiveLanguage($langcode);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -1474,7 +1558,7 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $this->updateFormLanguage($form_state);
 | 
			
		||||
    $form_langcode = $this->getFormLanguage();
 | 
			
		||||
    $form_langcode = $this->getActiveLanguage();
 | 
			
		||||
 | 
			
		||||
    foreach (field_info_instances($this->entityType, $this->bundle) as $instance) {
 | 
			
		||||
      $field_name = $instance['field_name'];
 | 
			
		||||
@@ -1496,7 +1580,7 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
 | 
			
		||||
   * @see EntityTranslationHandlerInterface::entityFormSubmit()
 | 
			
		||||
   */
 | 
			
		||||
  public function entityFormSubmit($form, &$form_state) {
 | 
			
		||||
    $form_langcode = $this->getFormLanguage();
 | 
			
		||||
    $form_langcode = $this->getActiveLanguage();
 | 
			
		||||
    $translations = $this->getTranslations();
 | 
			
		||||
    $is_translation = !empty($form_state['entity_translation']['is_translation']);
 | 
			
		||||
    $new_translation = !isset($translations->data[$form_langcode]);
 | 
			
		||||
@@ -1551,7 +1635,7 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
 | 
			
		||||
 | 
			
		||||
    if (count($translations->data) > 0) {
 | 
			
		||||
      $languages = language_list();
 | 
			
		||||
      $form_langcode = $this->getFormLanguage();
 | 
			
		||||
      $form_langcode = $this->getActiveLanguage();
 | 
			
		||||
      $language_tabs = array();
 | 
			
		||||
 | 
			
		||||
      if ($this->getSourceLanguage()) {
 | 
			
		||||
@@ -1624,7 +1708,7 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
 | 
			
		||||
   * Returns TRUE if an entity translation is being edited.
 | 
			
		||||
   */
 | 
			
		||||
  protected function isTranslationForm() {
 | 
			
		||||
    return !$this->isNewEntity() && $this->getFormLanguage() != $this->getLanguage();
 | 
			
		||||
    return !$this->isNewEntity() && $this->getActiveLanguage() != $this->getLanguage();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@@ -1653,7 +1737,7 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
 | 
			
		||||
   *
 | 
			
		||||
   * @throws Exception
 | 
			
		||||
   */
 | 
			
		||||
  private function initPathVariables() {
 | 
			
		||||
  protected function initPathVariables() {
 | 
			
		||||
    if (empty($this->pathScheme) || !isset($this->entityInfo['translation']['entity_translation']['path schemes'][$this->pathScheme])) {
 | 
			
		||||
      throw new Exception("Cannot initialize entity translation path variables (invalid path scheme).");
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -87,10 +87,7 @@ class EntityTranslationHandlerFactory {
 | 
			
		||||
    if (!isset($this->handlers[$entity_type][$id])) {
 | 
			
		||||
      $entity_info = entity_get_info($entity_type);
 | 
			
		||||
      $class = $entity_info['translation']['entity_translation']['class'];
 | 
			
		||||
      // @todo Remove the fourth parameter once 3rd-party translation handlers
 | 
			
		||||
      //   have been fixed and no longer require the deprecated entity_id
 | 
			
		||||
      //   parameter.
 | 
			
		||||
      $handler = new $class($entity_type, $entity_info, $entity, NULL);
 | 
			
		||||
      $handler = new $class($entity_type, $entity_info, $entity);
 | 
			
		||||
      $handler->setFactory($this);
 | 
			
		||||
      $this->handlers[$entity_type][$id] = $handler;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,9 @@ class EntityTranslationTestCase extends DrupalWebTestCase {
 | 
			
		||||
  protected $admin_user;
 | 
			
		||||
  protected $translator_user;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  function setUp() {
 | 
			
		||||
    $args = func_get_args();
 | 
			
		||||
    call_user_func_array(array('parent', 'setUp'), $args);
 | 
			
		||||
@@ -133,6 +136,19 @@ class EntityTranslationTestCase extends DrupalWebTestCase {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Disable a language which is in the language list.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string $langcode
 | 
			
		||||
   *   The code of the language to disable, which must exist.
 | 
			
		||||
   */
 | 
			
		||||
  function disableLanguage($langcode) {
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'enabled[' . $langcode . ']' => FALSE,
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('admin/config/regional/language', $edit, 'Save configuration');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Install a specified language if it has not been already, otherwise make sure that the language is enabled.
 | 
			
		||||
   *
 | 
			
		||||
@@ -190,7 +206,7 @@ class EntityTranslationTestCase extends DrupalWebTestCase {
 | 
			
		||||
 | 
			
		||||
    // Check if the setting works.
 | 
			
		||||
    $this->drupalGet('node/add/page');
 | 
			
		||||
    $this->assertFieldById('edit-body-und-add-more', t('Add another item'), t('Add another item button found.'));
 | 
			
		||||
    $this->assertFieldById('edit-body-en-add-more', t('Add another item'), t('Add another item button found.'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@@ -205,9 +221,8 @@ class EntityTranslationTestCase extends DrupalWebTestCase {
 | 
			
		||||
   */
 | 
			
		||||
  function createPage($title, $body, $langcode) {
 | 
			
		||||
    $edit = array();
 | 
			
		||||
    $language_none = LANGUAGE_NONE;
 | 
			
		||||
    $edit["title"] = $title;
 | 
			
		||||
    $edit["body[$language_none][0][value]"] = $body;
 | 
			
		||||
    $edit["body[$langcode][0][value]"] = $body;
 | 
			
		||||
    $edit['language'] = $langcode;
 | 
			
		||||
    $this->drupalPost('node/add/page', $edit, t('Save'));
 | 
			
		||||
    $this->assertRaw(t('Basic page %title has been created.', array('%title' => $title)), t('Basic page created.'));
 | 
			
		||||
@@ -270,10 +285,27 @@ class EntityTranslationTranslationTestCase extends EntityTranslationTestCase {
 | 
			
		||||
    $this->login($this->getAdminUser());
 | 
			
		||||
    $this->addLanguage('en');
 | 
			
		||||
    $this->addLanguage('es');
 | 
			
		||||
    $this->addLanguage('fr');
 | 
			
		||||
    $this->disableLanguage('fr');
 | 
			
		||||
    $this->configureContentType();
 | 
			
		||||
    $this->login($this->getTranslatorUser());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Test disabled languages.
 | 
			
		||||
   *
 | 
			
		||||
   * Make sure disabled languages are not accessible in the language list when
 | 
			
		||||
   * the option entity_translation_languages_enabled is enabled.
 | 
			
		||||
   */
 | 
			
		||||
  function testDisabledLanguages() {
 | 
			
		||||
    $this->drupalGet('node/add/page');
 | 
			
		||||
    $this->assertRaw('value="fr"', 'French is available even if the language is disabled');
 | 
			
		||||
 | 
			
		||||
    variable_set('entity_translation_languages_enabled', TRUE);
 | 
			
		||||
    $this->drupalGet('node/add/page');
 | 
			
		||||
    $this->assertNoRaw('value="fr"', 'French is not available when the language is disabled and the option entity_translation_languages_enabled is enabled.');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Test if field based translation works.
 | 
			
		||||
   *
 | 
			
		||||
@@ -525,3 +557,788 @@ class EntityTranslationHookTestCase extends EntityTranslationTestCase {
 | 
			
		||||
    return $info;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests that entity translation handler hierarchy works properly.
 | 
			
		||||
 */
 | 
			
		||||
class EntityTranslationHierarchyTestCase extends EntityTranslationTestCase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Return the test information.
 | 
			
		||||
   */
 | 
			
		||||
  public static function getInfo() {
 | 
			
		||||
    return array(
 | 
			
		||||
      'name' => 'Entity translation hierarchy',
 | 
			
		||||
      'description' => 'Tests that entity translation handler hierarchy works properly.',
 | 
			
		||||
      'group' => 'Entity translation',
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  function setUp() {
 | 
			
		||||
    parent::setUp('locale', 'entity_translation');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the handler hierarchy.
 | 
			
		||||
   */
 | 
			
		||||
  public function testHierarchy() {
 | 
			
		||||
    $entity_type = 'node';
 | 
			
		||||
    $node = $this->drupalCreateNode();
 | 
			
		||||
    $factory = EntityTranslationHandlerFactory::getInstance();
 | 
			
		||||
    $handler = $factory->getHandler($entity_type, $node);
 | 
			
		||||
 | 
			
		||||
    $children = array();
 | 
			
		||||
    foreach (range(0, 4) as $index) {
 | 
			
		||||
      $children[$index] = $this->drupalCreateNode();
 | 
			
		||||
      $handler->addChild($entity_type, $children[$index]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $langcode = 'it';
 | 
			
		||||
    $handler->setActiveLanguage($langcode);
 | 
			
		||||
    foreach ($children as $child) {
 | 
			
		||||
      $child_handler = $factory->getHandler($entity_type, $child);
 | 
			
		||||
      $this->assertEqual($child_handler->getActiveLanguage(), $langcode);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $rm_index = mt_rand(0, count($children) - 1);
 | 
			
		||||
    $handler->removeChild($entity_type, $children[$rm_index]);
 | 
			
		||||
 | 
			
		||||
    $langcode = 'fr';
 | 
			
		||||
    $handler->setActiveLanguage($langcode);
 | 
			
		||||
    foreach ($children as $index => $child) {
 | 
			
		||||
      $child_handler = $factory->getHandler($entity_type, $child);
 | 
			
		||||
      $this->assertEqual($child_handler->getActiveLanguage() == $langcode, $index != $rm_index);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // @todo Test the other properties.
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Basic tests for nodes using both content and entity translation.
 | 
			
		||||
 */
 | 
			
		||||
class EntityTranslationContentTranslationTestCase extends EntityTranslationTestCase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Return the test information.
 | 
			
		||||
   */
 | 
			
		||||
  public static function getInfo() {
 | 
			
		||||
    return array(
 | 
			
		||||
      'name' => 'Content and entity translation',
 | 
			
		||||
      'description' => 'Basic tests for nodes using both content and entity translatio.',
 | 
			
		||||
      'group' => 'Entity translation',
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function setUp() {
 | 
			
		||||
    // Activate modules and unset users.
 | 
			
		||||
    parent::setUp('locale', 'translation', 'translation_test', 'entity_translation');
 | 
			
		||||
    // Create admin and translator users with one extra permission,
 | 
			
		||||
    // namely the 'translate content' permission.
 | 
			
		||||
    // These getters works also as setters.
 | 
			
		||||
    $this->getAdminUser(array(
 | 
			
		||||
      'translate content',
 | 
			
		||||
    ));
 | 
			
		||||
    $this->getTranslatorUser(array(
 | 
			
		||||
      'translate content',
 | 
			
		||||
    ));
 | 
			
		||||
    $this->login($this->getAdminUser());
 | 
			
		||||
    $this->addLanguage('en');
 | 
			
		||||
    $this->addLanguage('es');
 | 
			
		||||
    $this->enableUrlLanguageDetection();
 | 
			
		||||
    $this->configureContentType();
 | 
			
		||||
    $this->login($this->getTranslatorUser());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configure the "Basic page" content type for entity translation tests.
 | 
			
		||||
   */
 | 
			
		||||
  public function configureContentType() {
 | 
			
		||||
    // Configure the "Basic page" content type to use multilingual support with
 | 
			
		||||
    // content translation.
 | 
			
		||||
    $edit = array();
 | 
			
		||||
    $edit['language_content_type'] = TRANSLATION_ENABLED;
 | 
			
		||||
    $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
 | 
			
		||||
    $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), t('Basic page content type has been updated.'));
 | 
			
		||||
 | 
			
		||||
    // Toggle body field's translatability.
 | 
			
		||||
    $edit = array();
 | 
			
		||||
    $edit['field[translatable]'] = 1;
 | 
			
		||||
    $this->drupalPost('admin/structure/types/manage/page/fields/body', $edit, t('Save settings'));
 | 
			
		||||
    $this->assertRaw(t('Saved %field configuration.', array('%field' => 'Body')), t('Body field settings have been updated.'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @see TranslationTestCase::createPage()
 | 
			
		||||
   */
 | 
			
		||||
  function createPage($title, $body, $language = NULL) {
 | 
			
		||||
    $edit = array();
 | 
			
		||||
    $langcode = LANGUAGE_NONE;
 | 
			
		||||
    $edit["title"] = $title;
 | 
			
		||||
    $edit["body[$langcode][0][value]"] = $body;
 | 
			
		||||
    if (!empty($language)) {
 | 
			
		||||
      $edit['language'] = $language;
 | 
			
		||||
    }
 | 
			
		||||
    $this->drupalPost('node/add/page', $edit, t('Save'));
 | 
			
		||||
    $this->assertRaw(t('Basic page %title has been created.', array('%title' => $title)), 'Basic page created.');
 | 
			
		||||
 | 
			
		||||
    // Check to make sure the node was created.
 | 
			
		||||
    $node = $this->drupalGetNodeByTitle($title);
 | 
			
		||||
    $this->assertTrue($node, 'Node found in database.');
 | 
			
		||||
 | 
			
		||||
    return $node;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests copying of source node's body value in the add translation form page.
 | 
			
		||||
   */
 | 
			
		||||
  public function testCopyFieldsUsingContentTranslation() {
 | 
			
		||||
    // Create Basic page in English.
 | 
			
		||||
    $node_title = $this->randomName();
 | 
			
		||||
    $node_body = $this->randomName();
 | 
			
		||||
    $node = $this->createPage($node_title, $node_body, 'en');
 | 
			
		||||
 | 
			
		||||
    // Check that the edit form correctly copies over the field's values from
 | 
			
		||||
    // the source node.
 | 
			
		||||
    $target_language = 'es';
 | 
			
		||||
    $this->drupalGet('node/add/page', array('query' => array('translation' => $node->nid, 'target' => $target_language)));
 | 
			
		||||
    $body_key = "body[${target_language}][0][value]";
 | 
			
		||||
    $this->assertFieldByXPath("//textarea[@name='$body_key']", $node_body, "Body field correctly instantiated with the value of the source language.");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests for integration of Entity Translation with other modules.
 | 
			
		||||
 */
 | 
			
		||||
class EntityTranslationIntegrationTestCase extends EntityTranslationTestCase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Return the test information.
 | 
			
		||||
   */
 | 
			
		||||
  public static function getInfo() {
 | 
			
		||||
    return array(
 | 
			
		||||
      'name' => 'Integration with other modules',
 | 
			
		||||
      'description' => 'Tests for integration of Entity Translation with other modules.',
 | 
			
		||||
      'group' => 'Entity translation',
 | 
			
		||||
      // We need to add this to the test_dependencies[] as well.
 | 
			
		||||
      'dependencies' => array('pathauto'),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function setUp() {
 | 
			
		||||
    // Activate modules.
 | 
			
		||||
    parent::setUp('locale', 'entity_translation');
 | 
			
		||||
    // Create admin and translator users with one extra permission,
 | 
			
		||||
    // namely the 'administer content' permission for the admin, to
 | 
			
		||||
    // allow enabling the pathauto module during testing. The
 | 
			
		||||
    // Translator user needs to be able to create url aliases.
 | 
			
		||||
    $this->getAdminUser(array(
 | 
			
		||||
      'administer modules',
 | 
			
		||||
    ));
 | 
			
		||||
    $this->getTranslatorUser(array(
 | 
			
		||||
      'create url aliases',
 | 
			
		||||
    ));
 | 
			
		||||
    $this->login($this->getAdminUser());
 | 
			
		||||
    $this->addLanguage('en');
 | 
			
		||||
    $this->addLanguage('es');
 | 
			
		||||
    $this->enableUrlLanguageDetection();
 | 
			
		||||
    $this->configureContentType();
 | 
			
		||||
    $this->login($this->getTranslatorUser());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns the role id of an $account object.
 | 
			
		||||
   */
 | 
			
		||||
  protected function getUserRole($account) {
 | 
			
		||||
    return reset($account->roles);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests Pathauto integration.
 | 
			
		||||
   */
 | 
			
		||||
  public function testPathautoIntegration() {
 | 
			
		||||
    $languages = language_list();
 | 
			
		||||
 | 
			
		||||
    // Enable the path module to add aliases manually.
 | 
			
		||||
    $this->login($this->getAdminUser());
 | 
			
		||||
    if (!module_exists('path')) {
 | 
			
		||||
      module_enable(array('path'));
 | 
			
		||||
    }
 | 
			
		||||
    $this->login($this->getTranslatorUser());
 | 
			
		||||
 | 
			
		||||
    // Create Basic page in English.
 | 
			
		||||
    $node_title = $this->randomName();
 | 
			
		||||
    $node_body = $this->randomName();
 | 
			
		||||
    $node = $this->createPage($node_title, $node_body, 'en');
 | 
			
		||||
    $node_alias = $this->randomName();
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'path[alias]' => $node_alias,
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
 | 
			
		||||
 | 
			
		||||
    // Submit translation in Spanish.
 | 
			
		||||
    $node_translation_body = $this->randomName();
 | 
			
		||||
    $this->createTranslation($node, $node_title, $node_translation_body, 'es');
 | 
			
		||||
    $node_translation_alias = $this->randomName();
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'path[alias]' => $node_translation_alias,
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'), array('language' => $languages['es']));
 | 
			
		||||
 | 
			
		||||
    // Enable the pathauto module.
 | 
			
		||||
    $this->login($this->getAdminUser());
 | 
			
		||||
    if (!module_exists('pathauto')) {
 | 
			
		||||
      module_enable(array('pathauto'));
 | 
			
		||||
    }
 | 
			
		||||
    $admin_rid = $this->getUserRole($this->getAdminUser());
 | 
			
		||||
    user_role_grant_permissions($admin_rid, array('administer url aliases', 'administer pathauto'));
 | 
			
		||||
    $translator_rid = $this->getUserRole($this->getTranslatorUser());
 | 
			
		||||
    user_role_grant_permissions($translator_rid, array('create url aliases'));
 | 
			
		||||
    $this->login($this->getTranslatorUser());
 | 
			
		||||
 | 
			
		||||
    // Create pathauto alias for source node.
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'path[pathauto]' => TRUE,
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
 | 
			
		||||
    // Clear the static caches in case they interfere.
 | 
			
		||||
    drupal_lookup_path('wipe');
 | 
			
		||||
    $node_pathauto_alias = pathauto_node_update_alias($node, 'return');
 | 
			
		||||
    $node_translation_pathauto_alias = pathauto_node_update_alias($node, 'return', array('language' => 'es'));
 | 
			
		||||
 | 
			
		||||
    // Check that the new alias for the translation matches the
 | 
			
		||||
    // pathauto's logic.
 | 
			
		||||
    $this->assertEqual($this->getUrl(), url(drupal_get_path_alias($node_pathauto_alias), array('absolute' => TRUE)));
 | 
			
		||||
 | 
			
		||||
    // Check that a pathauto alias was created for the source and
 | 
			
		||||
    // matches the pathauto's logic.
 | 
			
		||||
    $this->drupalGet('node/' . $node->nid, array('language' => $languages['es']));
 | 
			
		||||
    $this->assertEqual($this->getUrl(), url(drupal_get_path_alias($node_translation_pathauto_alias), array('absolute' => TRUE, 'language' => $languages['es'])));
 | 
			
		||||
 | 
			
		||||
    // Delete the two aliases.
 | 
			
		||||
    path_delete(array('source' => 'node/' . $node->nid));
 | 
			
		||||
 | 
			
		||||
    // Create pathauto alias for the translation of the node.
 | 
			
		||||
    $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'), array('language' => $languages['es']));
 | 
			
		||||
    // Clear the static caches in case they interfere.
 | 
			
		||||
    drupal_lookup_path('wipe');
 | 
			
		||||
    $node_pathauto_alias = pathauto_node_update_alias($node, 'return');
 | 
			
		||||
    $node_translation_pathauto_alias = pathauto_node_update_alias($node, 'return', array('language' => 'es'));
 | 
			
		||||
 | 
			
		||||
    // Check that the new alias for the translation matches the
 | 
			
		||||
    // pathauto's logic.
 | 
			
		||||
    $this->assertEqual($this->getUrl(), url(drupal_get_path_alias($node_translation_pathauto_alias), array('absolute' => TRUE, 'language' => $languages['es'])));
 | 
			
		||||
 | 
			
		||||
    // Check that a pathauto alias was created for the source and
 | 
			
		||||
    // matches the pathauto's logic.
 | 
			
		||||
    $this->drupalGet('node/' . $node->nid);
 | 
			
		||||
    $this->assertEqual($this->getUrl(), url(drupal_get_path_alias($node_pathauto_alias), array('absolute' => TRUE)));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests for enabling fields to use Entity Translation or disabling them.
 | 
			
		||||
 */
 | 
			
		||||
class EntityTranslationToggleFieldsTranslatabilityTestCase extends EntityTranslationTestCase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public static function getInfo() {
 | 
			
		||||
    return array(
 | 
			
		||||
      'name' => 'Fields translatability toggling',
 | 
			
		||||
      'description' => 'Tests for enabling fields to use Entity Translation or disabling them.',
 | 
			
		||||
      'group' => 'Entity translation',
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function setUp() {
 | 
			
		||||
    // Activate modules.
 | 
			
		||||
    parent::setUp('locale', 'taxonomy', 'entity_translation', 'entity_translation_test');
 | 
			
		||||
    $this->login($this->getAdminUser(array(
 | 
			
		||||
      'administer taxonomy',
 | 
			
		||||
      'toggle field translatability',
 | 
			
		||||
    )));
 | 
			
		||||
    $this->login($this->getTranslatorUser(array(
 | 
			
		||||
      'administer taxonomy',
 | 
			
		||||
    )));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configure the "Basic page" content type for entity translation tests.
 | 
			
		||||
   */
 | 
			
		||||
  protected function configureContentTypeForRevisions() {
 | 
			
		||||
    // Configure the "Basic page" content type to use revisions.
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'node_options[revision]' => 1,
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
 | 
			
		||||
    $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), t('Basic page content type has been updated.'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create a "Basic page" in the specified language.
 | 
			
		||||
   *
 | 
			
		||||
   * @param $title
 | 
			
		||||
   *   Title of the basic page in the specified language.
 | 
			
		||||
   * @param $body
 | 
			
		||||
   *   Body of the basic page in the specified language.
 | 
			
		||||
   */
 | 
			
		||||
  protected function createUntranslatedPage($title, $body) {
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'title' => $title,
 | 
			
		||||
      'body[und][0][value]' => $body,
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('node/add/page', $edit, t('Save'));
 | 
			
		||||
    $this->assertRaw(t('Basic page %title has been created.', array('%title' => $title)), t('Basic page created.'));
 | 
			
		||||
 | 
			
		||||
    // Check to make sure the node was created.
 | 
			
		||||
    $node = $this->drupalGetNodeByTitle($title);
 | 
			
		||||
    $this->assertTrue($node, t('Node found in database.'));
 | 
			
		||||
 | 
			
		||||
    return $node;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create a "Tags" term in the specified language.
 | 
			
		||||
   *
 | 
			
		||||
   * @param $name
 | 
			
		||||
   *   Name of the term.
 | 
			
		||||
   * @param $description
 | 
			
		||||
   *   Description of the term.
 | 
			
		||||
   * @param $text
 | 
			
		||||
   *   Content for the field_simple_text field.
 | 
			
		||||
   */
 | 
			
		||||
  protected function createUntranslatedTag($name, $description, $text) {
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'name' => $name,
 | 
			
		||||
      'description[value]' => $description,
 | 
			
		||||
      "field_simple_text[und][0][value]" => $text,
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('admin/structure/taxonomy/tags/add', $edit, t('Save'));
 | 
			
		||||
 | 
			
		||||
    // Check to make sure the term was created.
 | 
			
		||||
    $term = current(entity_load('taxonomy_term', FALSE, array('name' => $name), TRUE));
 | 
			
		||||
    $this->assertTrue($term, t('Term found in database.'));
 | 
			
		||||
 | 
			
		||||
    return $term;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests toggling translatability on fields with data (non-revisionable).
 | 
			
		||||
   */
 | 
			
		||||
  public function testTogglingFieldsWithDataNonRevisionable() {
 | 
			
		||||
    // Create an untranslated Basic page.
 | 
			
		||||
    $node_title = $this->randomName();
 | 
			
		||||
    $node_body = $this->randomName();
 | 
			
		||||
    $node = $this->createUntranslatedPage($node_title, $node_body);
 | 
			
		||||
    $this->assert(isset($node->body[LANGUAGE_NONE]), t('Found body field data in LANGUAGE_NONE as expected.'));
 | 
			
		||||
    $this->assertEqual($node->body[LANGUAGE_NONE][0]['value'], $node_body);
 | 
			
		||||
 | 
			
		||||
    // Create an untranslated Tags term.
 | 
			
		||||
    $term_name = $this->randomName();
 | 
			
		||||
    $term_description = $this->randomName();
 | 
			
		||||
    $term_simple_text = $this->randomName();
 | 
			
		||||
    $term = $this->createUntranslatedTag($term_name, $term_description, $term_simple_text);
 | 
			
		||||
    $this->assert(isset($term->field_simple_text[LANGUAGE_NONE]), t('Found field data in LANGUAGE_NONE as expected.'));
 | 
			
		||||
    $this->assertEqual($term->field_simple_text[LANGUAGE_NONE][0]['value'], $term_simple_text);
 | 
			
		||||
 | 
			
		||||
    // Enable translation for field body and check field migration.
 | 
			
		||||
    $this->login($this->getAdminUser());
 | 
			
		||||
    $this->drupalGet('admin/structure/types/manage/page/fields/body');
 | 
			
		||||
    $this->clickLink('Enable translation');
 | 
			
		||||
    $this->drupalPost(NULL, array(), t('Confirm'));
 | 
			
		||||
    $node = current(entity_load('node', FALSE, array('title' => $node_title), TRUE));
 | 
			
		||||
    $this->assert(isset($node->body['en']), t('Found field data in English as expected.'));
 | 
			
		||||
    $this->assertEqual($node->body['en'][0]['value'], $node_body);
 | 
			
		||||
    $this->assert(!isset($node->body[LANGUAGE_NONE]), t('No field data in LANGUAGE_NONE found.'));
 | 
			
		||||
 | 
			
		||||
    // Disable translation for body field and check field reverse migration.
 | 
			
		||||
    $this->drupalGet('admin/structure/types/manage/page/fields/body');
 | 
			
		||||
    $this->clickLink('Disable translation');
 | 
			
		||||
    $this->drupalPost(NULL, array(), t('Confirm'));
 | 
			
		||||
    $node = current(entity_load('node', FALSE, array('title' => $node_title), TRUE));
 | 
			
		||||
    $this->assert(isset($node->body[LANGUAGE_NONE]), t('Found field data in LANGUAGE_NONE as expected.'));
 | 
			
		||||
    $this->assertEqual($node->body[LANGUAGE_NONE][0]['value'], $node_body);
 | 
			
		||||
    $this->assert(!isset($node->body['en']), t('No field data in English found.'));
 | 
			
		||||
 | 
			
		||||
    // Enable translation for field_simple_text and check field migration.
 | 
			
		||||
    $this->drupalGet('admin/structure/taxonomy/tags/fields/field_simple_text');
 | 
			
		||||
    $this->clickLink('Enable translation');
 | 
			
		||||
    $this->drupalPost(NULL, array(), t('Confirm'));
 | 
			
		||||
    // Clear the field cache in order to load current field data.
 | 
			
		||||
    field_info_cache_clear();
 | 
			
		||||
    // Load the term and check that the fields data are under 'en'.
 | 
			
		||||
    $term = current(entity_load('taxonomy_term', FALSE, array('name' => $term_name), TRUE));
 | 
			
		||||
    $this->assert(isset($term->field_simple_text['en']), t('Found field data in English as expected.'));
 | 
			
		||||
    $this->assertEqual($term->field_simple_text['en'][0]['value'], $term_simple_text);
 | 
			
		||||
    $this->assert(!isset($term->field_simple_text[LANGUAGE_NONE]), t('No field data in LANGUAGE_NONE found.'));
 | 
			
		||||
 | 
			
		||||
    // Disable translation for field_simple_text.
 | 
			
		||||
    $this->drupalGet('admin/structure/taxonomy/tags/fields/field_simple_text');
 | 
			
		||||
    $this->clickLink('Disable translation');
 | 
			
		||||
    $this->drupalPost(NULL, array(), t('Confirm'));
 | 
			
		||||
 | 
			
		||||
    // Load the term and check that the fields data are under LANGUAGE_NONE.
 | 
			
		||||
    $term = current(entity_load('taxonomy_term', FALSE, array('name' => $term_name), TRUE));
 | 
			
		||||
    $this->assert(isset($term->field_simple_text[LANGUAGE_NONE]), t('Found field data in LANGUAGE_NONE as expected.'));
 | 
			
		||||
    $this->assertEqual($term->field_simple_text[LANGUAGE_NONE][0]['value'], $term_simple_text);
 | 
			
		||||
    $this->assert(!isset($term->field_simple_text['en']), t('No field data in English found.'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests toggling translatability on fields with data (revisionable).
 | 
			
		||||
   */
 | 
			
		||||
  public function testTogglingFieldsWithDataRevisionable() {
 | 
			
		||||
    // Enable revisions for Basic pages.
 | 
			
		||||
    $this->login($this->getAdminUser());
 | 
			
		||||
    $this->configureContentTypeForRevisions();
 | 
			
		||||
 | 
			
		||||
    // Create an untranslated Basic page.
 | 
			
		||||
    $this->login($this->getTranslatorUser());
 | 
			
		||||
    $node_title = $this->randomName();
 | 
			
		||||
    $node_body = $this->randomName();
 | 
			
		||||
    $node = $this->createUntranslatedPage($node_title, $node_body);
 | 
			
		||||
    $this->assert(isset($node->body[LANGUAGE_NONE]), t('Found field data in LANGUAGE_NONE as expected.'));
 | 
			
		||||
    $this->assertEqual($node->body[LANGUAGE_NONE][0]['value'], $node_body);
 | 
			
		||||
 | 
			
		||||
    // Create a new revision for the page.
 | 
			
		||||
    $edit_revision = array(
 | 
			
		||||
      'title' => $this->randomName(),
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('node/' . $node->nid . '/edit', $edit_revision, t('Save'));
 | 
			
		||||
    $node = node_load($node->nid, NULL, TRUE);
 | 
			
		||||
    $this->assert($node->vid == $node->nid + 1, t('Correct vid attached to the node object.'));
 | 
			
		||||
 | 
			
		||||
    // Enable translation for field body and check field migration on all
 | 
			
		||||
    // revisions.
 | 
			
		||||
    $this->login($this->getAdminUser());
 | 
			
		||||
    $this->drupalGet('admin/structure/types/manage/page/fields/body');
 | 
			
		||||
    $this->clickLink('Enable translation');
 | 
			
		||||
    $this->drupalPost(NULL, array(), t('Confirm'));
 | 
			
		||||
    $node_current_revision = current(entity_load('node', FALSE, array('vid' => $node->vid), TRUE));
 | 
			
		||||
    $this->assert(isset($node_current_revision->body['en']), t('Found field data in English as expected.'));
 | 
			
		||||
    $this->assertEqual($node_current_revision->body['en'][0]['value'], $node_body);
 | 
			
		||||
    $this->assert(!isset($node_current_revision->body[LANGUAGE_NONE]), t('No field data in LANGUAGE_NONE found.'));
 | 
			
		||||
    $node_previous_revision = current(entity_load('node', FALSE, array('vid' => ($node->vid - 1)), TRUE));
 | 
			
		||||
    $this->assert(isset($node_previous_revision->body['en']), t('Found field data in English as expected.'));
 | 
			
		||||
    $this->assertEqual($node_previous_revision->body['en'][0]['value'], $node_body);
 | 
			
		||||
    $this->assert(!isset($node_previous_revision->body[LANGUAGE_NONE]), t('No field data in LANGUAGE_NONE found.'));
 | 
			
		||||
 | 
			
		||||
    // Disable translation for field_body.
 | 
			
		||||
    $this->drupalGet('admin/structure/types/manage/page/fields/body');
 | 
			
		||||
    $this->clickLink('Disable translation');
 | 
			
		||||
    $this->drupalPost(NULL, array(), t('Confirm'));
 | 
			
		||||
 | 
			
		||||
    // Disable translation for field body and check field reverse migration on
 | 
			
		||||
    // all revisions.
 | 
			
		||||
    $node_current_revision = current(entity_load('node', FALSE, array('vid' => $node->vid), TRUE));
 | 
			
		||||
    $this->assert(isset($node_current_revision->body[LANGUAGE_NONE]), t('Found field data in LANGUAGE_NONE as expected.'));
 | 
			
		||||
    $this->assertEqual($node_current_revision->body[LANGUAGE_NONE][0]['value'], $node_body);
 | 
			
		||||
    $this->assert(!isset($node_current_revision->body['en']), t('No field data in English found.'));
 | 
			
		||||
    $node_previous_revision = current(entity_load('node', FALSE, array('vid' => ($node->vid - 1)), TRUE));
 | 
			
		||||
    $this->assert(isset($node_previous_revision->body[LANGUAGE_NONE]), t('Found field data in LANGUAGE_NONE as expected.'));
 | 
			
		||||
    $this->assertEqual($node_previous_revision->body[LANGUAGE_NONE][0]['value'], $node_body);
 | 
			
		||||
    $this->assert(!isset($node_previous_revision->body['en']), t('No field data in English found.'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests for the taxonomy autocomplete translation modes.
 | 
			
		||||
 */
 | 
			
		||||
class EntityTranslationTaxonomyAutocompleteTestCase extends EntityTranslationTestCase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns the test information.
 | 
			
		||||
   */
 | 
			
		||||
  public static function getInfo() {
 | 
			
		||||
    return array(
 | 
			
		||||
      'name' => 'Entity translation taxonomy autocomplete',
 | 
			
		||||
      'description' => 'Tests for the taxonomy autocomplete translation modes.',
 | 
			
		||||
      'group' => 'Entity translation',
 | 
			
		||||
      'dependencies' => array('title'),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  function setUp() {
 | 
			
		||||
    parent::setUp('locale', 'entity_translation', 'taxonomy', 'title');
 | 
			
		||||
    $this->login($this->getAdminUser(array(
 | 
			
		||||
      'administer taxonomy',
 | 
			
		||||
      'administer entity translation',
 | 
			
		||||
    )));
 | 
			
		||||
    $this->addLanguage('en');
 | 
			
		||||
    $this->addLanguage('it');
 | 
			
		||||
    $this->addLanguage('fr');
 | 
			
		||||
    $this->enableUrlLanguageDetection();
 | 
			
		||||
    $this->configureVocabulary();
 | 
			
		||||
    $this->configureContentType();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Makes the "Tags" vocabulary translatable.
 | 
			
		||||
   */
 | 
			
		||||
  function configureVocabulary() {
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'entity_translation_entity_types[taxonomy_term]' => TRUE,
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('admin/config/regional/entity_translation', $edit, t('Save configuration'));
 | 
			
		||||
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'entity_translation_taxonomy' => TRUE,
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('admin/structure/taxonomy/tags/edit', $edit, t('Save'));
 | 
			
		||||
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'enabled' => TRUE,
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('admin/structure/taxonomy/tags/fields/replace/name', $edit, t('Save settings'));
 | 
			
		||||
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'enabled' => TRUE,
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('admin/structure/taxonomy/tags/fields/replace/description', $edit, t('Save settings'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  function configureContentType() {
 | 
			
		||||
    parent::configureContentType();
 | 
			
		||||
 | 
			
		||||
    // Create an untranslatable term reference field with unlimited cardinality.
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'fields[_add_new_field][label]' => 'Test tags',
 | 
			
		||||
      'fields[_add_new_field][field_name]' => 'test_tags',
 | 
			
		||||
      'fields[_add_new_field][type]' => 'taxonomy_term_reference',
 | 
			
		||||
      'fields[_add_new_field][widget_type]' => 'taxonomy_autocomplete',
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('admin/structure/types/manage/page/fields', $edit, t('Save'));
 | 
			
		||||
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'field[settings][allowed_values][0][vocabulary]' => 'tags',
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('admin/structure/types/manage/page/fields/field_test_tags/field-settings', $edit, t('Save field settings'));
 | 
			
		||||
 | 
			
		||||
    // Verify the in-place translation option is available.
 | 
			
		||||
    $this->drupalGet('admin/structure/types/manage/page/fields/field_test_tags');
 | 
			
		||||
    $this->assertRaw(t('Enable in-place translation of terms'));
 | 
			
		||||
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'field[cardinality]' => FIELD_CARDINALITY_UNLIMITED,
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost(NULL, $edit, t('Save settings'));
 | 
			
		||||
 | 
			
		||||
    // Ensure entity info is up-to-date.
 | 
			
		||||
    drupal_flush_all_caches();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Enables in-place translation.
 | 
			
		||||
   */
 | 
			
		||||
  function enableInPlaceTranslation() {
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'instance[settings][entity_translation_taxonomy_autocomplete_translate]' => TRUE,
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('admin/structure/types/manage/page/fields/field_test_tags', $edit, t('Save settings'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests that in-place translation works as expected.
 | 
			
		||||
   */
 | 
			
		||||
  function testInPlaceTranslation() {
 | 
			
		||||
    $this->enableInPlaceTranslation();
 | 
			
		||||
    $this->login($this->getTranslatorUser(array(
 | 
			
		||||
      'administer taxonomy',
 | 
			
		||||
    )));
 | 
			
		||||
 | 
			
		||||
    $values = array(
 | 
			
		||||
      'Red' => 'Rosso',
 | 
			
		||||
      'Green' => 'Verde',
 | 
			
		||||
      'Blue' => 'Blu',
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // Create an English node with a few new tags.
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'title' => 'Test 1',
 | 
			
		||||
      'field_test_tags[' . LANGUAGE_NONE . ']' => implode(', ', array_keys($values)),
 | 
			
		||||
      'language' => 'en',
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('node/add/page', $edit, t('Save'));
 | 
			
		||||
    $node = $this->drupalGetNodeByTitle($edit['title']);
 | 
			
		||||
 | 
			
		||||
    // Create an Italian translation and translate the English tags.
 | 
			
		||||
    $this->drupalGet('node/' . $node->nid . '/translate');
 | 
			
		||||
    $this->clickLink('add', 1);
 | 
			
		||||
    $edit = array();
 | 
			
		||||
    foreach (array_values($values) as $delta => $value) {
 | 
			
		||||
      $edit['field_test_tags[' . LANGUAGE_NONE . '][' . $delta . ']'] = $value;
 | 
			
		||||
    }
 | 
			
		||||
    $this->drupalPost(NULL, $edit, t('Save'));
 | 
			
		||||
 | 
			
		||||
    // Verify that the Italian values are correctly stored/displayed.
 | 
			
		||||
    foreach ($values as $original => $translation) {
 | 
			
		||||
      $this->assertRaw($translation);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Verify that the original English values were correctly retained.
 | 
			
		||||
    $this->drupalGet('node/' . $node->nid);
 | 
			
		||||
    foreach ($values as $original => $translation) {
 | 
			
		||||
      $this->assertRaw($original);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * That the autocomplete works with translated terms.
 | 
			
		||||
   */
 | 
			
		||||
  function testTranslatedAutocomplete() {
 | 
			
		||||
    $this->login($this->getTranslatorUser(array(
 | 
			
		||||
      'administer taxonomy',
 | 
			
		||||
    )));
 | 
			
		||||
 | 
			
		||||
    $vocabulary = taxonomy_vocabulary_machine_name_load('tags');
 | 
			
		||||
    $entity_type = 'taxonomy_term';
 | 
			
		||||
    $existing_values = array();
 | 
			
		||||
    $translated_values = array(
 | 
			
		||||
      'en' => array(
 | 
			
		||||
        'Red' => 'Rosso',
 | 
			
		||||
        'Green' => 'Verde',
 | 
			
		||||
      ),
 | 
			
		||||
      'it' => array(
 | 
			
		||||
        'Blu' => 'Blue',
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    $langcodes = array_keys($translated_values);
 | 
			
		||||
 | 
			
		||||
    // Create a few existing tags with different original language and translate
 | 
			
		||||
    // them accordingly.
 | 
			
		||||
    foreach ($translated_values as $langcode => $values) {
 | 
			
		||||
      title_active_language($langcode);
 | 
			
		||||
      $translation_langcode = current(array_diff($langcodes, array($langcode)));
 | 
			
		||||
 | 
			
		||||
      foreach ($values as $original => $translation) {
 | 
			
		||||
        $term = (object) array(
 | 
			
		||||
          'vid' => $vocabulary->vid,
 | 
			
		||||
          'vocabulary_machine_name' => $vocabulary->machine_name,
 | 
			
		||||
          'name' => $original,
 | 
			
		||||
          'name_field' => array(
 | 
			
		||||
            $langcode => array(array('value' => $original)),
 | 
			
		||||
            $translation_langcode => array(array('value' => $translation)),
 | 
			
		||||
          ),
 | 
			
		||||
        );
 | 
			
		||||
        $translation = array(
 | 
			
		||||
          'language' => $translation_langcode,
 | 
			
		||||
          'source' => $langcode,
 | 
			
		||||
          'status' => TRUE,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $handler = entity_translation_get_handler($entity_type, $term);
 | 
			
		||||
        $handler->setOriginalLanguage($langcode);
 | 
			
		||||
        $handler->initTranslations();
 | 
			
		||||
        $handler->setTranslation($translation);
 | 
			
		||||
        taxonomy_term_save($term);
 | 
			
		||||
 | 
			
		||||
        $existing_values[$term->name_field['en'][0]['value']] = $term->name_field['it'][0]['value'];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Verify that the English autocomplete route returns results for terms
 | 
			
		||||
    // originally created in English.
 | 
			
		||||
    $this->autocompleteGet('en', 'Re');
 | 
			
		||||
    $this->assertRaw('Red');
 | 
			
		||||
    $this->assertRaw('Green');
 | 
			
		||||
 | 
			
		||||
    // Verify that the English autocomplete route returns results for terms
 | 
			
		||||
    // translated into English.
 | 
			
		||||
    $this->autocompleteGet('en', 'Blu');
 | 
			
		||||
    $this->assertRaw('Blue');
 | 
			
		||||
 | 
			
		||||
    // Verify that the Italian autocomplete route returns results for terms
 | 
			
		||||
    // originally created in Italian.
 | 
			
		||||
    $this->autocompleteGet('it', 'Blu');
 | 
			
		||||
    $this->assertRaw('Blu');
 | 
			
		||||
    $this->assertNoRaw('Blue');
 | 
			
		||||
 | 
			
		||||
    // Verify that the Italian autocomplete route returns results for terms
 | 
			
		||||
    // translated into Italian.
 | 
			
		||||
    $this->autocompleteGet('it', 'R');
 | 
			
		||||
    $this->assertRaw('Rosso');
 | 
			
		||||
    $this->assertRaw('Verde');
 | 
			
		||||
 | 
			
		||||
    // Verify that existing tags are correctly referenced and new tags are
 | 
			
		||||
    // correctly created, when saving an English node.
 | 
			
		||||
    $new_values = array(
 | 
			
		||||
      'Cyan' => 'Ciano',
 | 
			
		||||
      'Magenta' => 'Magenta',
 | 
			
		||||
      'Yellow' => 'Giallo',
 | 
			
		||||
      'Black' => 'Nero',
 | 
			
		||||
    );
 | 
			
		||||
    $all_values = $existing_values + $new_values;
 | 
			
		||||
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'title' => 'Test 1',
 | 
			
		||||
      'field_test_tags[' . LANGUAGE_NONE . ']' => implode(', ', array_keys($all_values)),
 | 
			
		||||
      'language' => 'en',
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost('node/add/page', $edit, t('Save'));
 | 
			
		||||
    foreach ($all_values as $original => $translation) {
 | 
			
		||||
      $this->assertRaw($original);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Verify that existing translated tags are correctly referenced and new
 | 
			
		||||
    // tags are correctly created, when translated the node into Italian.
 | 
			
		||||
    $node = $this->drupalGetNodeByTitle($edit['title']);
 | 
			
		||||
    $this->drupalGet('node/' . $node->nid . '/translate');
 | 
			
		||||
    $this->clickLink('add', 1);
 | 
			
		||||
    $edit = array(
 | 
			
		||||
      'field_test_tags[' . LANGUAGE_NONE . ']' => implode(', ', $all_values),
 | 
			
		||||
    );
 | 
			
		||||
    $this->drupalPost(NULL, $edit, t('Save'));
 | 
			
		||||
    foreach ($all_values as $original => $translation) {
 | 
			
		||||
      $this->assertRaw($translation);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Verify that existing (translated) tags were preserved, while new Italian
 | 
			
		||||
    // tags replaced the corresponding English versions.
 | 
			
		||||
    $this->drupalGet('node/' . $node->nid);
 | 
			
		||||
    foreach ($existing_values as $original => $translation) {
 | 
			
		||||
      $this->assertRaw($original);
 | 
			
		||||
    }
 | 
			
		||||
    foreach ($new_values as $original => $translation) {
 | 
			
		||||
      $this->assertRaw($translation);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Performs a GET request to the autocomplete path.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string $langcode
 | 
			
		||||
   *   The language to use to query results.
 | 
			
		||||
   * @param string $query
 | 
			
		||||
   *   The search query string.
 | 
			
		||||
   */
 | 
			
		||||
  protected function autocompleteGet($langcode, $query) {
 | 
			
		||||
    $path = 'entity_translation/taxonomy_term/autocomplete/' . $langcode . '/field_test_tags/' . $query;
 | 
			
		||||
    $languages = language_list();
 | 
			
		||||
    $this->drupalGet($path, array('language' => $languages[$langcode]));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,11 +4,11 @@ core = 7.x
 | 
			
		||||
package = Testing
 | 
			
		||||
hidden = TRUE
 | 
			
		||||
dependencies[] = entity_translation
 | 
			
		||||
 | 
			
		||||
files[] = entity_translation_test.module
 | 
			
		||||
 | 
			
		||||
; Information added by Drupal.org packaging script on 2016-09-28
 | 
			
		||||
version = "7.x-1.0-beta5+15-dev"
 | 
			
		||||
; Information added by Drupal.org packaging script on 2019-01-20
 | 
			
		||||
version = "7.x-1.0+5-dev"
 | 
			
		||||
core = "7.x"
 | 
			
		||||
project = "entity_translation"
 | 
			
		||||
datestamp = "1475057941"
 | 
			
		||||
 | 
			
		||||
datestamp = "1548022384"
 | 
			
		||||
 
 | 
			
		||||
@@ -5,3 +5,34 @@
 | 
			
		||||
 * Installation functionality for Entity Translation testing module.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements hook_install().
 | 
			
		||||
 */
 | 
			
		||||
function entity_translation_test_install() {
 | 
			
		||||
  // Create a simple text field, attached to taxonomy_terms.
 | 
			
		||||
  field_info_cache_clear();
 | 
			
		||||
 | 
			
		||||
  $field = array(
 | 
			
		||||
    'field_name' => 'field_simple_text',
 | 
			
		||||
    'type' => 'text',
 | 
			
		||||
    'cardinality' => 1,
 | 
			
		||||
  );
 | 
			
		||||
  field_create_field($field);
 | 
			
		||||
 | 
			
		||||
  $instance = array(
 | 
			
		||||
    'field_name' => $field['field_name'],
 | 
			
		||||
    'label' => ucfirst(str_replace('_', ' ', $field['field_name'])),
 | 
			
		||||
    'entity_type' => 'taxonomy_term',
 | 
			
		||||
    'bundle' => 'tags',
 | 
			
		||||
    'widget' => array(
 | 
			
		||||
      'type' => 'text_textfield',
 | 
			
		||||
    ),
 | 
			
		||||
    'display' => array(
 | 
			
		||||
      'default' => array(
 | 
			
		||||
        'type' => 'text_default',
 | 
			
		||||
      ),
 | 
			
		||||
    ),
 | 
			
		||||
  );
 | 
			
		||||
  field_create_instance($instance);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,8 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Contains the relationship plugin for relating entities to translation metadata.
 | 
			
		||||
 * Contains a views plugin for relating entities to translation metadata.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -27,7 +28,10 @@ class entity_translation_handler_relationship extends views_handler_relationship
 | 
			
		||||
    $alias = $def['table'] . '_' . $this->table;
 | 
			
		||||
    // We need to add a condition on entity type to the join to avoid getting
 | 
			
		||||
    // relationships to entities with other types.
 | 
			
		||||
    $join->extra = "$alias.entity_type = '{$def['entity type']}'";
 | 
			
		||||
    $join->extra = array(
 | 
			
		||||
      array('field' => 'entity_type', 'value' => $def['entity type']),
 | 
			
		||||
    );
 | 
			
		||||
    $this->alias = $this->query->add_relationship($alias, $join, 'entity_translation', $this->relationship);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user