Issue #2019055 by plach, fago, kfritsche: Switch from field-level language fallback to entity-level language fallback.
parent
b9dfcae3f9
commit
46942cd373
|
@ -218,7 +218,7 @@ services:
|
|||
arguments: ['@event_dispatcher', '@service_container', '@controller_resolver']
|
||||
language_manager:
|
||||
class: Drupal\Core\Language\LanguageManager
|
||||
arguments: ['@state']
|
||||
arguments: ['@state', '@module_handler']
|
||||
string_translator.custom_strings:
|
||||
class: Drupal\Core\StringTranslation\Translator\CustomStrings
|
||||
arguments: ['@settings']
|
||||
|
|
|
@ -545,30 +545,6 @@ function language_url_split_prefix($path, $languages) {
|
|||
return array(FALSE, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the possible fallback languages ordered by language weight.
|
||||
*
|
||||
* @param
|
||||
* (optional) The language type. Defaults to Language::TYPE_CONTENT.
|
||||
*
|
||||
* @return
|
||||
* An array of language codes.
|
||||
*/
|
||||
function language_fallback_get_candidates($type = Language::TYPE_CONTENT) {
|
||||
$fallback_candidates = &drupal_static(__FUNCTION__);
|
||||
|
||||
if (!isset($fallback_candidates)) {
|
||||
// Get languages ordered by weight, add Language::LANGCODE_NOT_SPECIFIED at the end.
|
||||
$fallback_candidates = array_keys(language_list());
|
||||
$fallback_candidates[] = Language::LANGCODE_NOT_SPECIFIED;
|
||||
|
||||
// Let other modules hook in and add/change candidates.
|
||||
drupal_alter('language_fallback_candidates', $fallback_candidates);
|
||||
}
|
||||
|
||||
return $fallback_candidates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "language_negotiation"
|
||||
*/
|
||||
|
|
|
@ -423,6 +423,12 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
|
|||
*/
|
||||
public function set($property_name, $value, $notify = TRUE) {
|
||||
$this->get($property_name)->setValue($value, FALSE);
|
||||
|
||||
if ($property_name == 'langcode') {
|
||||
// Avoid using unset as this unnecessarily triggers magic methods later
|
||||
// on.
|
||||
$this->language = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -658,6 +664,7 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
|
|||
$translation->values = &$this->values;
|
||||
$translation->fields = &$this->fields;
|
||||
$translation->translations = &$this->translations;
|
||||
$translation->enforceIsNew = &$this->enforceIsNew;
|
||||
$translation->translationInitialize = FALSE;
|
||||
|
||||
return $translation;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\Core\Entity;
|
||||
|
||||
use Drupal\Core\Language\Language;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Entity form controller variant for content entity types.
|
||||
|
@ -16,6 +17,32 @@ use Drupal\Core\Language\Language;
|
|||
*/
|
||||
class ContentEntityFormController extends EntityFormController {
|
||||
|
||||
/**
|
||||
* The entity manager.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* Constructs a ContentEntityFormController object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $entity_manager) {
|
||||
$this->entityManager = $entity_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -38,6 +65,7 @@ class ContentEntityFormController extends EntityFormController {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function validate(array $form, array &$form_state) {
|
||||
$this->updateFormLangcode($form_state);
|
||||
$entity = $this->buildEntity($form, $form_state);
|
||||
$entity_type = $entity->entityType();
|
||||
$entity_langcode = $entity->language()->id;
|
||||
|
@ -73,53 +101,22 @@ class ContentEntityFormController extends EntityFormController {
|
|||
protected function init(array &$form_state) {
|
||||
// Ensure we act on the translation object corresponding to the current form
|
||||
// language.
|
||||
$this->entity = $this->getTranslatedEntity($form_state);
|
||||
parent::init($form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the translation object corresponding to the form language.
|
||||
*
|
||||
* @param array $form_state
|
||||
* A keyed array containing the current state of the form.
|
||||
*/
|
||||
protected function getTranslatedEntity(array $form_state) {
|
||||
$langcode = $this->getFormLangcode($form_state);
|
||||
$translation = $this->entity->getTranslation($langcode);
|
||||
// Ensure that the entity object is a BC entity if the original one is.
|
||||
return $this->entity instanceof EntityBCDecorator ? $translation->getBCEntity() : $translation;
|
||||
$this->entity = $this->entity->getTranslation($langcode);
|
||||
parent::init($form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormLangcode(array $form_state) {
|
||||
$entity = $this->entity;
|
||||
if (!empty($form_state['langcode'])) {
|
||||
$langcode = $form_state['langcode'];
|
||||
}
|
||||
else {
|
||||
// If no form langcode was provided we default to the current content
|
||||
// language and inspect existing translations to find a valid fallback,
|
||||
// if any.
|
||||
$translations = $entity->getTranslationLanguages();
|
||||
$languageManager = \Drupal::languageManager();
|
||||
$langcode = $languageManager->getLanguage(Language::TYPE_CONTENT)->id;
|
||||
$fallback = $languageManager->isMultilingual() ? language_fallback_get_candidates() : array();
|
||||
while (!empty($langcode) && !isset($translations[$langcode])) {
|
||||
$langcode = array_shift($fallback);
|
||||
}
|
||||
}
|
||||
|
||||
// If the site is not multilingual or no translation for the given form
|
||||
// language is available, fall back to the entity language.
|
||||
if (!empty($langcode)) {
|
||||
return $langcode;
|
||||
}
|
||||
else {
|
||||
// If the entity is translatable, return the original language.
|
||||
return $entity->getUntranslated()->language()->id;
|
||||
public function getFormLangcode(array &$form_state) {
|
||||
if (empty($form_state['langcode'])) {
|
||||
// Imply a 'view' operation to ensure users edit entities in the same
|
||||
// language they are displayed. This allows to keep contextual editing
|
||||
// working also for multilingual entities.
|
||||
$form_state['langcode'] = $this->entityManager->getTranslationFromContext($this->entity)->language()->id;
|
||||
}
|
||||
return $form_state['langcode'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,8 +133,8 @@ class ContentEntityFormController extends EntityFormController {
|
|||
$entity = clone $this->entity;
|
||||
$entity_type = $entity->entityType();
|
||||
$info = entity_get_info($entity_type);
|
||||
// @todo Exploit the Field API to process the submitted entity fields.
|
||||
|
||||
// @todo Exploit the Entity Field API to process the submitted field values.
|
||||
// Copy top-level form values that are entity fields but not handled by
|
||||
// field API without changing existing entity fields that are not being
|
||||
// edited by this form. Values of fields handled by field API are copied
|
||||
|
@ -163,4 +160,5 @@ class ContentEntityFormController extends EntityFormController {
|
|||
}
|
||||
return $entity;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -269,6 +269,7 @@ class EntityFormController extends FormBase implements EntityFormControllerInter
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function validate(array $form, array &$form_state) {
|
||||
$this->updateFormLangcode($form_state);
|
||||
// @todo Remove this.
|
||||
// Execute legacy global validation handlers.
|
||||
unset($form_state['validate_handlers']);
|
||||
|
@ -292,8 +293,6 @@ class EntityFormController extends FormBase implements EntityFormControllerInter
|
|||
public function submit(array $form, array &$form_state) {
|
||||
// Remove button and internal Form API values from submitted values.
|
||||
form_state_values_clean($form_state);
|
||||
|
||||
$this->updateFormLangcode($form_state);
|
||||
$this->entity = $this->buildEntity($form, $form_state);
|
||||
return $this->entity;
|
||||
}
|
||||
|
@ -325,7 +324,7 @@ class EntityFormController extends FormBase implements EntityFormControllerInter
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormLangcode(array $form_state) {
|
||||
public function getFormLangcode(array &$form_state) {
|
||||
return $this->entity->language()->id;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ interface EntityFormControllerInterface extends BaseFormIdInterface {
|
|||
* @return string
|
||||
* The form language code.
|
||||
*/
|
||||
public function getFormLangcode(array $form_state);
|
||||
public function getFormLangcode(array &$form_state);
|
||||
|
||||
/**
|
||||
* Checks whether the current form language matches the entity one.
|
||||
|
|
|
@ -91,7 +91,7 @@ interface EntityInterface extends AccessibleInterface {
|
|||
*
|
||||
* @param $langcode
|
||||
* (optional) The language code of the language that should be used for
|
||||
* getting the label. If set to NULL, the entity's default language is
|
||||
* getting the label. If set to NULL, the entity's active language is
|
||||
* used.
|
||||
*
|
||||
* @return
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace Drupal\Core\Entity;
|
|||
use Drupal\Component\Plugin\PluginManagerBase;
|
||||
use Drupal\Component\Plugin\Factory\DefaultFactory;
|
||||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Language\LanguageManager;
|
||||
use Drupal\Core\Language\Language;
|
||||
|
@ -17,8 +18,8 @@ use Drupal\Core\Plugin\Discovery\AlterDecorator;
|
|||
use Drupal\Core\Plugin\Discovery\CacheDecorator;
|
||||
use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
|
||||
use Drupal\Core\Plugin\Discovery\InfoHookDecorator;
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\Core\StringTranslation\TranslationInterface;
|
||||
use Drupal\Core\TypedData\TranslatableInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
|
@ -456,4 +457,37 @@ class EntityManager extends PluginManagerBase implements EntityManagerInterface
|
|||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTranslationFromContext(EntityInterface $entity, $langcode = NULL, $context = array()) {
|
||||
$translation = $entity;
|
||||
|
||||
if ($entity instanceof TranslatableInterface) {
|
||||
if (empty($langcode)) {
|
||||
$langcode = $this->languageManager->getLanguage(Language::TYPE_CONTENT)->id;
|
||||
}
|
||||
|
||||
// Retrieve language fallback candidates to perform the entity language
|
||||
// negotiation.
|
||||
$context['data'] = $entity;
|
||||
$context += array('operation' => 'entity_view');
|
||||
$candidates = $this->languageManager->getFallbackCandidates($langcode, $context);
|
||||
|
||||
// Ensure the default language has the proper language code.
|
||||
$default_language = $entity->getUntranslated()->language();
|
||||
$candidates[$default_language->id] = Language::LANGCODE_DEFAULT;
|
||||
|
||||
// Return the most fitting entity translation.
|
||||
foreach ($candidates as $candidate) {
|
||||
if ($entity->hasTranslation($candidate)) {
|
||||
$translation = $entity->getTranslation($candidate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $translation;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -244,4 +244,27 @@ interface EntityManagerInterface extends PluginManagerInterface {
|
|||
*/
|
||||
public function getBundleInfo($entity_type);
|
||||
|
||||
/**
|
||||
* Returns the entity translation to be used in the given context.
|
||||
*
|
||||
* This will check whether a translation for the desired language is available
|
||||
* and if not, it will fall back to the most appropriate translation based on
|
||||
* the provided context.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity whose translation will be returned.
|
||||
* @param string $langcode
|
||||
* (optional) The language of the current context. Defaults to the current
|
||||
* content language.
|
||||
* @param array $context
|
||||
* (optional) An associative array of arbitrary data that can be useful to
|
||||
* determine the proper fallback sequence.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityInterface
|
||||
* An entity object for the translated data.
|
||||
*
|
||||
* @see \Drupal\Core\Language\LanguageManager::getFallbackCandidates()
|
||||
*/
|
||||
public function getTranslationFromContext(EntityInterface $entity, $langcode = NULL, $context = array());
|
||||
|
||||
}
|
||||
|
|
|
@ -7,13 +7,15 @@
|
|||
|
||||
namespace Drupal\Core\Entity;
|
||||
|
||||
use Drupal\entity\Entity\EntityDisplay;
|
||||
use Drupal\Core\Entity\EntityManager;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\entity\Entity\EntityDisplay;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Base class for entity view controllers.
|
||||
*/
|
||||
class EntityViewBuilder implements EntityViewBuilderInterface {
|
||||
class EntityViewBuilder implements EntityControllerInterface, EntityViewBuilderInterface {
|
||||
|
||||
/**
|
||||
* The type of entities for which this controller is instantiated.
|
||||
|
@ -31,6 +33,13 @@ class EntityViewBuilder implements EntityViewBuilderInterface {
|
|||
*/
|
||||
protected $entityInfo;
|
||||
|
||||
/**
|
||||
* The entity manager service.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* An array of view mode info for the type of entities for which this
|
||||
* controller is instantiated.
|
||||
|
@ -49,12 +58,30 @@ class EntityViewBuilder implements EntityViewBuilderInterface {
|
|||
*/
|
||||
protected $cacheBin = 'cache';
|
||||
|
||||
public function __construct($entity_type) {
|
||||
/**
|
||||
* Constructs a new EntityViewBuilder.
|
||||
*
|
||||
* @param string $entity_type
|
||||
* The entity type.
|
||||
* @param array $entity_info
|
||||
* The entity information array.
|
||||
* @param \Drupal\Core\Entity\EntityManager $entity_manager
|
||||
* The entity manager service.
|
||||
*/
|
||||
public function __construct($entity_type, array $entity_info, EntityManager $entity_manager) {
|
||||
$this->entityType = $entity_type;
|
||||
$this->entityInfo = entity_get_info($entity_type);
|
||||
$this->entityInfo = $entity_info;
|
||||
$this->entityManager = $entity_manager;
|
||||
$this->viewModesInfo = entity_get_view_modes($entity_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) {
|
||||
return new static($entity_type, $entity_info, $container->get('entity.manager'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -167,9 +194,14 @@ class EntityViewBuilder implements EntityViewBuilderInterface {
|
|||
$view_modes = array();
|
||||
$displays = array();
|
||||
$context = array('langcode' => $langcode);
|
||||
foreach ($entities as $entity) {
|
||||
foreach ($entities as $key => $entity) {
|
||||
$bundle = $entity->bundle();
|
||||
|
||||
// Ensure that from now on we are dealing with the proper translation
|
||||
// object.
|
||||
$entity = $this->entityManager->getTranslationFromContext($entity, $langcode);
|
||||
$entities[$key] = $entity;
|
||||
|
||||
// Allow modules to change the view mode.
|
||||
$entity_view_mode = $view_mode;
|
||||
drupal_alter('entity_view_mode', $entity_view_mode, $entity, $context);
|
||||
|
|
|
@ -153,7 +153,7 @@ class Language {
|
|||
* @param array $languages
|
||||
* The array of language objects keyed by langcode.
|
||||
*/
|
||||
public static function sort($languages) {
|
||||
public static function sort(&$languages) {
|
||||
uasort($languages, function ($a, $b) {
|
||||
$a_weight = isset($a->weight) ? $a->weight : 0;
|
||||
$b_weight = isset($b->weight) ? $b->weight : 0;
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
|
||||
namespace Drupal\Core\Language;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Drupal\Component\Utility\MapArray;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Class responsible for initializing each language type.
|
||||
|
@ -29,6 +31,13 @@ class LanguageManager {
|
|||
*/
|
||||
protected $state = NULL;
|
||||
|
||||
/**
|
||||
* The module handler service.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* An array of language objects keyed by language type.
|
||||
*
|
||||
|
@ -57,10 +66,13 @@ class LanguageManager {
|
|||
* Constructs an LanguageManager object.
|
||||
*
|
||||
* @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface $state
|
||||
* The state keyvalue store.
|
||||
* (optional) The state keyvalue store. Defaults to NULL.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* (optional) The module handler service. Defaults to NULL.
|
||||
*/
|
||||
public function __construct(KeyValueStoreInterface $state = NULL) {
|
||||
public function __construct(KeyValueStoreInterface $state = NULL, ModuleHandlerInterface $module_handler = NULL) {
|
||||
$this->state = $state;
|
||||
$this->moduleHandler = $module_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -161,6 +173,53 @@ class LanguageManager {
|
|||
return ($this->state->get('language_count') ?: 1) > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language fallback candidates for a given context.
|
||||
*
|
||||
* @param string $langcode
|
||||
* (optional) The language of the current context. Defaults to NULL.
|
||||
* @param array $context
|
||||
* (optional) An associative array of data that can be useful to determine
|
||||
* the fallback sequence. The following keys are used in core:
|
||||
* - langcode: The desired language.
|
||||
* - operation: The name of the operation indicating the context where
|
||||
* language fallback is being applied, e.g. 'entity_view'.
|
||||
* - data: An arbitrary data structure that makes sense in the provided
|
||||
* context, e.g. an entity.
|
||||
*
|
||||
* @return array
|
||||
* An array of language codes sorted by priority: first values should be
|
||||
* tried first.
|
||||
*/
|
||||
public function getFallbackCandidates($langcode = NULL, array $context = array()) {
|
||||
if ($this->isMultilingual()) {
|
||||
// Get languages ordered by weight, add Language::LANGCODE_NOT_SPECIFIED at
|
||||
// the end.
|
||||
$candidates = array_keys(language_list());
|
||||
$candidates[] = Language::LANGCODE_NOT_SPECIFIED;
|
||||
$candidates = MapArray::copyValuesToKeys($candidates);
|
||||
|
||||
// The first candidate should always be the desired language if specified.
|
||||
if (!empty($langcode)) {
|
||||
$candidates = array($langcode => $langcode) + $candidates;
|
||||
}
|
||||
|
||||
// Let other modules hook in and add/change candidates.
|
||||
$type = 'language_fallback_candidates';
|
||||
$types = array();
|
||||
if (!empty($context['operation'])) {
|
||||
$types[] = $type . '_' . $context['operation'];
|
||||
}
|
||||
$types[] = $type;
|
||||
$this->moduleHandler->alter($types, $candidates, $context);
|
||||
}
|
||||
else {
|
||||
$candidates = array(Language::LANGCODE_DEFAULT);
|
||||
}
|
||||
|
||||
return $candidates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of the available language types.
|
||||
*
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
namespace Drupal\Core\TypedData;
|
||||
|
||||
use Drupal\Core\Language\LanguageManager;
|
||||
|
||||
/**
|
||||
* Interface for translatable data.
|
||||
*/
|
||||
|
@ -35,10 +37,9 @@ interface TranslatableInterface {
|
|||
/**
|
||||
* Gets a translation of the data.
|
||||
*
|
||||
* The returned translation has to be implement the same typed data interfaces
|
||||
* as this typed data object, excluding the TranslatableInterface. E.g., if
|
||||
* this typed data object implements the ComplexDataInterface and
|
||||
* AccessibleInterface, the translation object has to implement both as well.
|
||||
* The returned translation has to be of the same type than this typed data
|
||||
* object. If the specified translation does not exist, a new one will be
|
||||
* instantiated.
|
||||
*
|
||||
* @param $langcode
|
||||
* The language code of the translation to get or Language::LANGCODE_DEFAULT
|
||||
|
@ -49,7 +50,6 @@ interface TranslatableInterface {
|
|||
*/
|
||||
public function getTranslation($langcode);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the translatable object referring to the original language.
|
||||
*
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace Drupal\aggregator;
|
|||
|
||||
use Drupal\Component\Utility\String;
|
||||
use Drupal\Core\Entity\ContentEntityFormController;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\aggregator\CategoryStorageControllerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
@ -19,13 +19,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
*/
|
||||
class FeedFormController extends ContentEntityFormController {
|
||||
|
||||
/**
|
||||
* The feed storage.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityStorageControllerInterface
|
||||
*/
|
||||
protected $feedStorageController;
|
||||
|
||||
/**
|
||||
* The category storage controller.
|
||||
*
|
||||
|
@ -36,13 +29,13 @@ class FeedFormController extends ContentEntityFormController {
|
|||
/**
|
||||
* Constructs a FeedForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityStorageControllerInterface $feed_storage
|
||||
* The feed storage.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\aggregator\CategoryStorageControllerInterface $category_storage_controller
|
||||
* The category storage controller.
|
||||
*/
|
||||
public function __construct(EntityStorageControllerInterface $feed_storage, CategoryStorageControllerInterface $category_storage_controller) {
|
||||
$this->feedStorageController = $feed_storage;
|
||||
public function __construct(EntityManagerInterface $entity_manager, CategoryStorageControllerInterface $category_storage_controller) {
|
||||
parent::__construct($entity_manager);
|
||||
$this->categoryStorageController = $category_storage_controller;
|
||||
}
|
||||
|
||||
|
@ -51,7 +44,7 @@ class FeedFormController extends ContentEntityFormController {
|
|||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('plugin.manager.entity')->getStorageController('aggregator_feed'),
|
||||
$container->get('entity.manager'),
|
||||
$container->get('aggregator.category.storage')
|
||||
);
|
||||
}
|
||||
|
@ -125,7 +118,8 @@ class FeedFormController extends ContentEntityFormController {
|
|||
public function validate(array $form, array &$form_state) {
|
||||
$feed = $this->buildEntity($form, $form_state);
|
||||
// Check for duplicate titles.
|
||||
$result = $this->feedStorageController->getFeedDuplicates($feed);
|
||||
$feed_storage_controller = $this->entityManager->getStorageController('aggregator_feed');
|
||||
$result = $feed_storage_controller->getFeedDuplicates($feed);
|
||||
foreach ($result as $item) {
|
||||
if (strcasecmp($item->title, $feed->label()) == 0) {
|
||||
form_set_error('title', $this->t('A feed named %feed already exists. Enter a unique title.', array('%feed' => $feed->label())));
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\book\Form;
|
||||
|
||||
use Drupal\Core\Entity\ContentEntityFormController;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\book\BookManager;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
|
@ -32,19 +33,25 @@ class BookOutlineForm extends ContentEntityFormController {
|
|||
|
||||
/**
|
||||
* Constructs a BookOutlineForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\book\BookManager $book_manager
|
||||
* The BookManager service.
|
||||
*/
|
||||
public function __construct(BookManager $bookManager) {
|
||||
$this->bookManager = $bookManager;
|
||||
public function __construct(EntityManagerInterface $entity_manager, BookManager $book_manager) {
|
||||
parent::__construct($entity_manager);
|
||||
$this->bookManager = $book_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method lets us inject the services this class needs.
|
||||
*
|
||||
* Only inject services that are actually needed. Which services
|
||||
* are needed will vary by the controller.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static($container->get('book.manager'));
|
||||
return new static(
|
||||
$container->get('entity.manager'),
|
||||
$container->get('book.manager')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -896,7 +896,7 @@ function comment_translation_configuration_element_submit($form, &$form_state) {
|
|||
$key = 'language_configuration';
|
||||
$comment_form_state = array(
|
||||
'content_translation' => array('key' => $key),
|
||||
'language' => array($key => array('entity_type' => 'comment', 'bundle' => $form['#field']['name'])),
|
||||
'language' => array($key => array('entity_type' => 'comment', 'bundle' => $form['#field']->name)),
|
||||
'values' => array($key => array('content_translation' => $form_state['values']['content_translation'])),
|
||||
);
|
||||
content_translation_language_configuration_element_submit($form, $comment_form_state);
|
||||
|
|
|
@ -23,13 +23,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
*/
|
||||
class CommentFormController extends ContentEntityFormController {
|
||||
|
||||
/**
|
||||
* The entity manager service.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* The field info service.
|
||||
*
|
||||
|
@ -58,13 +51,28 @@ class CommentFormController extends ContentEntityFormController {
|
|||
* @param \Drupal\Core\Session\AccountInterface $current_user
|
||||
* The current user.
|
||||
*/
|
||||
|
||||
public function __construct(EntityManagerInterface $entity_manager, FieldInfo $field_info, AccountInterface $current_user) {
|
||||
$this->entityManager = $entity_manager;
|
||||
parent::__construct($entity_manager);
|
||||
$this->fieldInfo = $field_info;
|
||||
$this->currentUser = $current_user;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function init(array &$form_state) {
|
||||
$comment = $this->entity;
|
||||
|
||||
// Make the comment inherit the current content language unless specifically
|
||||
// set.
|
||||
if ($comment->isNew()) {
|
||||
$language_content = \Drupal::languageManager()->getLanguage(Language::TYPE_CONTENT);
|
||||
$comment->langcode->value = $language_content->id;
|
||||
}
|
||||
|
||||
parent::init($form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\Core\Entity\EntityFormController::form().
|
||||
*/
|
||||
|
@ -207,13 +215,6 @@ class CommentFormController extends ContentEntityFormController {
|
|||
'#value' => ($comment->id() ? !$comment->uid->target_id : $this->currentUser->isAnonymous()),
|
||||
);
|
||||
|
||||
// Make the comment inherit the current content language unless specifically
|
||||
// set.
|
||||
if ($comment->isNew()) {
|
||||
$language_content = language(Language::TYPE_CONTENT);
|
||||
$comment->langcode->value = $language_content->id;
|
||||
}
|
||||
|
||||
// Add internal comment properties.
|
||||
$original = $comment->getUntranslated();
|
||||
foreach (array('cid', 'pid', 'entity_id', 'entity_type', 'field_id', 'uid', 'langcode') as $key) {
|
||||
|
|
|
@ -23,13 +23,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
*/
|
||||
class CommentViewBuilder extends EntityViewBuilder implements EntityViewBuilderInterface, EntityControllerInterface {
|
||||
|
||||
/**
|
||||
* The entity manager service.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* The field info service.
|
||||
*
|
||||
|
@ -57,6 +50,7 @@ class CommentViewBuilder extends EntityViewBuilder implements EntityViewBuilderI
|
|||
public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) {
|
||||
return new static(
|
||||
$entity_type,
|
||||
$entity_info,
|
||||
$container->get('entity.manager'),
|
||||
$container->get('field.info'),
|
||||
$container->get('module_handler'),
|
||||
|
@ -69,6 +63,8 @@ class CommentViewBuilder extends EntityViewBuilder implements EntityViewBuilderI
|
|||
*
|
||||
* @param string $entity_type
|
||||
* The entity type.
|
||||
* @param array $entity_info
|
||||
* The entity information array.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager service.
|
||||
* @param \Drupal\field\FieldInfo $field_info
|
||||
|
@ -78,9 +74,8 @@ class CommentViewBuilder extends EntityViewBuilder implements EntityViewBuilderI
|
|||
* @param \Drupal\Core\Access\CsrfTokenGenerator $csrf_token
|
||||
* The CSRF token manager service.
|
||||
*/
|
||||
public function __construct($entity_type, EntityManagerInterface $entity_manager, FieldInfo $field_info, ModuleHandlerInterface $module_handler, CsrfTokenGenerator $csrf_token) {
|
||||
parent::__construct($entity_type);
|
||||
$this->entityManager = $entity_manager;
|
||||
public function __construct($entity_type, array $entity_info, EntityManagerInterface $entity_manager, FieldInfo $field_info, ModuleHandlerInterface $module_handler, CsrfTokenGenerator $csrf_token) {
|
||||
parent::__construct($entity_type, $entity_info, $entity_manager);
|
||||
$this->fieldInfo = $field_info;
|
||||
$this->moduleHandler = $module_handler;
|
||||
$this->csrfToken = $csrf_token;
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace Drupal\comment\Form;
|
|||
use Drupal\comment\CommentManagerInterface;
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Entity\ContentEntityConfirmFormBase;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
|
@ -27,10 +28,13 @@ class DeleteForm extends ContentEntityConfirmFormBase {
|
|||
/**
|
||||
* Constructs a DeleteForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\comment\CommentManagerInterface $comment_manager
|
||||
* The comment manager service.
|
||||
*/
|
||||
public function __construct(CommentManagerInterface $comment_manager) {
|
||||
public function __construct(EntityManagerInterface $entity_manager, CommentManagerInterface $comment_manager) {
|
||||
parent::__construct($entity_manager);
|
||||
$this->commentManager = $comment_manager;
|
||||
}
|
||||
|
||||
|
@ -39,6 +43,7 @@ class DeleteForm extends ContentEntityConfirmFormBase {
|
|||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager'),
|
||||
$container->get('comment.manager')
|
||||
);
|
||||
}
|
||||
|
|
|
@ -323,7 +323,12 @@ function content_translation_translate_access(EntityInterface $entity) {
|
|||
*/
|
||||
function content_translation_view_access(EntityInterface $entity, $langcode, AccountInterface $account = NULL) {
|
||||
$entity_type = $entity->entityType();
|
||||
return !empty($entity->translation[$langcode]['status']) || user_access('translate any entity', $account) || user_access("translate $entity_type entities", $account);
|
||||
$info = $entity->entityInfo();
|
||||
$permission = "translate $entity_type";
|
||||
if (!empty($info['permission_granularity']) && $info['permission_granularity'] == 'bundle') {
|
||||
$permission = "translate {$entity->bundle()} $entity_type";
|
||||
}
|
||||
return !empty($entity->translation[$langcode]['status']) || user_access('translate any entity', $account) || user_access($permission, $account);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -627,7 +632,10 @@ function content_translation_permission() {
|
|||
* Implements hook_form_alter().
|
||||
*/
|
||||
function content_translation_form_alter(array &$form, array &$form_state) {
|
||||
if (($form_controller = content_translation_form_controller($form_state)) && ($entity = $form_controller->getEntity()) && !$entity->isNew() && $entity instanceof ContentEntityInterface && $entity->isTranslatable()) {
|
||||
$form_controller = content_translation_form_controller($form_state);
|
||||
$entity = $form_controller ? $form_controller->getEntity() : NULL;
|
||||
|
||||
if ($entity instanceof ContentEntityInterface && $entity->isTranslatable() && count($entity->getTranslationLanguages()) > 1) {
|
||||
$controller = content_translation_controller($entity->entityType());
|
||||
$controller->entityFormAlter($form, $form_state, $entity);
|
||||
|
||||
|
@ -650,28 +658,16 @@ function content_translation_form_alter(array &$form, array &$form_state) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_language_alter().
|
||||
* Implements hook_language_fallback_candidates_OPERATION_alter().
|
||||
*
|
||||
* Performs language fallback for unaccessible translations.
|
||||
*/
|
||||
function content_translation_field_language_alter(&$display_language, $context) {
|
||||
$entity = $context['entity'];
|
||||
$entity_type = $entity->entityType();
|
||||
|
||||
if ($entity instanceof ContentEntityInterface && isset($entity->translation[$context['langcode']]) && $entity->isTranslatable() && !content_translation_view_access($entity, $context['langcode'])) {
|
||||
$instances = field_info_instances($entity_type, $entity->bundle());
|
||||
// Avoid altering the real entity.
|
||||
$entity = clone($entity);
|
||||
$entity_langcode = $entity->getUntranslated()->language()->id;
|
||||
|
||||
foreach ($entity->translation as $langcode => $translation) {
|
||||
if ($langcode == $context['langcode'] || !content_translation_view_access($entity, $langcode)) {
|
||||
$entity->removeTranslation($langcode);
|
||||
}
|
||||
function content_translation_language_fallback_candidates_entity_view_alter(&$candidates, $context) {
|
||||
$entity = $context['data'];
|
||||
foreach ($entity->getTranslationLanguages() as $langcode => $language) {
|
||||
if (!content_translation_view_access($entity, $langcode)) {
|
||||
unset($candidates[$langcode]);
|
||||
}
|
||||
|
||||
// Find the new fallback values.
|
||||
field_language_fallback($display_language, $entity, $context['langcode']);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,18 +34,18 @@ abstract class ContentTranslationUITest extends ContentTranslationTestBase {
|
|||
* Tests the basic translation UI.
|
||||
*/
|
||||
function testTranslationUI() {
|
||||
$this->assertBasicTranslation();
|
||||
$this->doTestBasicTranslation();
|
||||
$this->doTestTranslationOverview();
|
||||
$this->assertOutdatedStatus();
|
||||
$this->assertPublishedStatus();
|
||||
$this->assertAuthoringInfo();
|
||||
$this->assertTranslationDeletion();
|
||||
$this->doTestOutdatedStatus();
|
||||
$this->doTestPublishedStatus();
|
||||
$this->doTestAuthoringInfo();
|
||||
$this->doTestTranslationDeletion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the basic translation workflow.
|
||||
*/
|
||||
protected function assertBasicTranslation() {
|
||||
protected function doTestBasicTranslation() {
|
||||
// Create a new test entity with original values in the default language.
|
||||
$default_langcode = $this->langcodes[0];
|
||||
$values[$default_langcode] = $this->getNewEntityValues($default_langcode);
|
||||
|
@ -117,7 +117,7 @@ abstract class ContentTranslationUITest extends ContentTranslationTestBase {
|
|||
/**
|
||||
* Tests up-to-date status tracking.
|
||||
*/
|
||||
protected function assertOutdatedStatus() {
|
||||
protected function doTestOutdatedStatus() {
|
||||
$entity = entity_load($this->entityType, $this->entityId, TRUE);
|
||||
$langcode = 'fr';
|
||||
$default_langcode = $this->langcodes[0];
|
||||
|
@ -150,7 +150,7 @@ abstract class ContentTranslationUITest extends ContentTranslationTestBase {
|
|||
/**
|
||||
* Tests the translation publishing status.
|
||||
*/
|
||||
protected function assertPublishedStatus() {
|
||||
protected function doTestPublishedStatus() {
|
||||
$entity = entity_load($this->entityType, $this->entityId, TRUE);
|
||||
$path = $this->controller->getEditPath($entity);
|
||||
|
||||
|
@ -172,7 +172,7 @@ abstract class ContentTranslationUITest extends ContentTranslationTestBase {
|
|||
/**
|
||||
* Tests the translation authoring information.
|
||||
*/
|
||||
protected function assertAuthoringInfo() {
|
||||
protected function doTestAuthoringInfo() {
|
||||
$entity = entity_load($this->entityType, $this->entityId, TRUE);
|
||||
$path = $this->controller->getEditPath($entity);
|
||||
$values = array();
|
||||
|
@ -194,8 +194,8 @@ abstract class ContentTranslationUITest extends ContentTranslationTestBase {
|
|||
|
||||
$entity = entity_load($this->entityType, $this->entityId, TRUE);
|
||||
foreach ($this->langcodes as $langcode) {
|
||||
$this->assertEqual($entity->translation[$langcode]['uid'] == $values[$langcode]['uid'], 'Translation author correctly stored.');
|
||||
$this->assertEqual($entity->translation[$langcode]['created'] == $values[$langcode]['created'], 'Translation date correctly stored.');
|
||||
$this->assertEqual($entity->translation[$langcode]['uid'], $values[$langcode]['uid'], 'Translation author correctly stored.');
|
||||
$this->assertEqual($entity->translation[$langcode]['created'], $values[$langcode]['created'], 'Translation date correctly stored.');
|
||||
}
|
||||
|
||||
// Try to post non valid values and check that they are rejected.
|
||||
|
@ -207,14 +207,14 @@ abstract class ContentTranslationUITest extends ContentTranslationTestBase {
|
|||
);
|
||||
$this->drupalPostForm($path, $edit, $this->getFormSubmitAction($entity));
|
||||
$this->assertTrue($this->xpath('//div[contains(@class, "error")]//ul'), 'Invalid values generate a list of form errors.');
|
||||
$this->assertEqual($entity->translation[$langcode]['uid'] == $values[$langcode]['uid'], 'Translation author correctly kept.');
|
||||
$this->assertEqual($entity->translation[$langcode]['created'] == $values[$langcode]['created'], 'Translation date correctly kept.');
|
||||
$this->assertEqual($entity->translation[$langcode]['uid'], $values[$langcode]['uid'], 'Translation author correctly kept.');
|
||||
$this->assertEqual($entity->translation[$langcode]['created'], $values[$langcode]['created'], 'Translation date correctly kept.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests translation deletion.
|
||||
*/
|
||||
protected function assertTranslationDeletion() {
|
||||
protected function doTestTranslationDeletion() {
|
||||
// Confirm and delete a translation.
|
||||
$langcode = 'fr';
|
||||
$entity = entity_load($this->entityType, $this->entityId, TRUE);
|
||||
|
|
|
@ -40,11 +40,11 @@ class EntityDisplayModeTest extends WebTestBase {
|
|||
$this->drupalGet('admin/structure/display-modes/view');
|
||||
$this->assertResponse(200);
|
||||
|
||||
$this->drupalGet('admin/structure/display-modes/view/add/entity_test_mul');
|
||||
$this->drupalGet('admin/structure/display-modes/view/add/entity_test_mulrev');
|
||||
$this->assertResponse(404);
|
||||
|
||||
$this->drupalGet('admin/structure/display-modes/view/add');
|
||||
$this->assertNoLink(t('Test entity - data table'), 'An entity type with no view builder cannot have view modes.');
|
||||
$this->assertNoLink(t('Test entity - revisions and data table'), 'An entity type with no view builder cannot have view modes.');
|
||||
|
||||
// Test adding a view mode.
|
||||
$this->clickLink(t('Test entity'));
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
language_fallback: true
|
||||
purge_batch_size: 10
|
||||
|
|
|
@ -4,9 +4,6 @@ field.settings:
|
|||
type: mapping
|
||||
label: 'Field settings'
|
||||
mapping:
|
||||
language_fallback:
|
||||
type: boolean
|
||||
label: 'Whether the field display falls back to global language fallback configuration'
|
||||
purge_batch_size:
|
||||
type: integer
|
||||
label: 'Maximum number of field data records to purge'
|
||||
|
|
|
@ -414,27 +414,6 @@ function hook_field_attach_view_alter(&$output, $context) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform alterations on field_language() values.
|
||||
*
|
||||
* This hook is invoked to alter the array of display language codes for the
|
||||
* given entity.
|
||||
*
|
||||
* @param $display_langcode
|
||||
* A reference to an array of language codes keyed by field name.
|
||||
* @param $context
|
||||
* An associative array containing:
|
||||
* - entity: The entity with fields to render.
|
||||
* - langcode: The language code $entity has to be displayed in.
|
||||
*/
|
||||
function hook_field_language_alter(&$display_langcode, $context) {
|
||||
// Do not apply core language fallback rules if they are disabled or if Locale
|
||||
// is not registered as a translation handler.
|
||||
if (field_language_fallback_enabled() && field_has_translation_handler($context['entity']->entityType())) {
|
||||
field_language_fallback($display_langcode, $context['entity'], $context['langcode']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter field_available_languages() values.
|
||||
*
|
||||
|
|
|
@ -120,19 +120,21 @@ function field_invoke_method($method, $target_function, EntityInterface $entity,
|
|||
$langcodes = _field_language_suggestion($available_langcodes, $options['langcode'], $field_name);
|
||||
|
||||
foreach ($langcodes as $langcode) {
|
||||
$items = $entity->getTranslation($langcode)->get($field_name);
|
||||
$items->filterEmptyValues();
|
||||
if ($entity->hasTranslation($langcode)) {
|
||||
$items = $entity->getTranslation($langcode)->get($field_name);
|
||||
$items->filterEmptyValues();
|
||||
|
||||
$result = $target->$method($items, $a, $b);
|
||||
$result = $target->$method($items, $a, $b);
|
||||
|
||||
if (isset($result)) {
|
||||
// For methods with array results, we merge results together.
|
||||
// For methods with scalar results, we collect results in an array.
|
||||
if (is_array($result)) {
|
||||
$return = array_merge($return, $result);
|
||||
}
|
||||
else {
|
||||
$return[] = $result;
|
||||
if (isset($result)) {
|
||||
// For methods with array results, we merge results together.
|
||||
// For methods with scalar results, we collect results in an array.
|
||||
if (is_array($result)) {
|
||||
$return = array_merge($return, $result);
|
||||
}
|
||||
else {
|
||||
$return[] = $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -223,10 +225,12 @@ function field_invoke_method_multiple($method, $target_function, array $entities
|
|||
$langcode = !empty($options['langcode'][$id]) ? $options['langcode'][$id] : $options['langcode'];
|
||||
$langcodes = _field_language_suggestion($available_langcodes, $langcode, $field_name);
|
||||
foreach ($langcodes as $langcode) {
|
||||
// Group the items corresponding to the current field.
|
||||
$items = $entity->getTranslation($langcode)->get($field_name);
|
||||
$items->filterEmptyValues();
|
||||
$grouped_items[$instance_uuid][$langcode][$id] = $items;
|
||||
if ($entity->hasTranslation($langcode)) {
|
||||
// Group the items corresponding to the current field.
|
||||
$items = $entity->getTranslation($langcode)->get($field_name);
|
||||
$items->filterEmptyValues();
|
||||
$grouped_items[$instance_uuid][$langcode][$id] = $items;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\ContentEntityInterface;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\entity\Entity\EntityDisplay;
|
||||
use Drupal\field\Field;
|
||||
|
||||
|
@ -858,3 +859,80 @@ function field_access($op, FieldInterface $field, $entity_type, $entity = NULL,
|
|||
$items = $entity ? $entity->get($field->id()) : NULL;
|
||||
return $access_controller->fieldAccess($op, $field, $account, $items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that a given language code is valid.
|
||||
*
|
||||
* Checks whether the given language code is one of the enabled language codes.
|
||||
* Otherwise, it returns the current, global language code; or the site's
|
||||
* default language code, if the additional parameter $default is TRUE.
|
||||
*
|
||||
* @param $langcode
|
||||
* The language code to validate.
|
||||
* @param $default
|
||||
* Whether to return the default language code or the current language code in
|
||||
* case $langcode is invalid.
|
||||
*
|
||||
* @return
|
||||
* A valid language code.
|
||||
*
|
||||
* @deprecated This has been deprecated in favor of the Entity Field API.
|
||||
*/
|
||||
function field_valid_language($langcode, $default = TRUE) {
|
||||
$languages = field_content_languages();
|
||||
if (in_array($langcode, $languages)) {
|
||||
return $langcode;
|
||||
}
|
||||
return $default ? language_default()->id : language(Language::TYPE_CONTENT)->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the display language code for the fields attached to the given
|
||||
* entity.
|
||||
*
|
||||
* The actual language code for each given field is determined based on the
|
||||
* requested language code and the actual data available in the fields
|
||||
* themselves.
|
||||
* If there is no registered translation handler for the given entity type, the
|
||||
* display language code to be used is just Language::LANGCODE_NOT_SPECIFIED, as
|
||||
* no other language code is allowed by field_available_languages().
|
||||
*
|
||||
* If translation handlers are found, we let modules provide alternative display
|
||||
* language codes for fields not having the requested language code available.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity to be displayed.
|
||||
* @param $field_name
|
||||
* (optional) The name of the field to be displayed. Defaults to NULL. If
|
||||
* no value is specified, the display language codes for every field attached
|
||||
* to the given entity will be returned.
|
||||
* @param $langcode
|
||||
* (optional) The language code $entity has to be displayed in. Defaults to
|
||||
* NULL. If no value is given the current language will be used.
|
||||
*
|
||||
* @return
|
||||
* A language code if a field name is specified, an array of language codes
|
||||
* keyed by field name otherwise.
|
||||
*
|
||||
* @see \Drupal\Core\Language\LanguageManager::getFallbackCandidates()
|
||||
* @see \Drupal\Core\Entity\EntityInterface::getFieldLangcode()
|
||||
*
|
||||
* @deprecated This has been deprecated in favor of the Entity Field API.
|
||||
*/
|
||||
function field_language(EntityInterface $entity, $field_name = NULL, $langcode = NULL) {
|
||||
$langcode = \Drupal::entityManager()->getTranslationFromContext($entity, $langcode)->language()->id;
|
||||
$definitions = $entity->getPropertyDefinitions();
|
||||
$translatable = field_has_translation_handler($entity->entityType());
|
||||
if (!isset($field_name)) {
|
||||
$display_langcodes = array();
|
||||
foreach ($definitions as $name => $definition) {
|
||||
if (!empty($definition['configurable'])) {
|
||||
$display_langcodes[$name] = $translatable ? $langcode : Language::LANGCODE_NOT_SPECIFIED;
|
||||
}
|
||||
}
|
||||
return $display_langcodes;
|
||||
}
|
||||
elseif (!empty($definitions[$field_name]['configurable'])) {
|
||||
return $translatable ? $langcode : Language::LANGCODE_NOT_SPECIFIED;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -442,10 +442,7 @@ function field_update_8003() {
|
|||
* @ingroup config_upgrade
|
||||
*/
|
||||
function field_update_8004() {
|
||||
update_variable_set('field_language_fallback', TRUE);
|
||||
update_variables_to_config('field.settings', array(
|
||||
'field_language_fallback' => 'language_fallback',
|
||||
));
|
||||
// Do nothing: the former update code has been moved to locale_update_8018().
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -65,49 +65,6 @@ use Drupal\field\FieldInterface;
|
|||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Applies language fallback rules to the fields attached to the given entity.
|
||||
*
|
||||
* Core language fallback rules simply check if fields have a field translation
|
||||
* for the requested language code. If so, the requested language is returned,
|
||||
* otherwise all the fallback candidates are inspected to see if there is a
|
||||
* field translation available in another language.
|
||||
* By default this is called by field_field_language_alter(), but this
|
||||
* behavior can be disabled by setting the 'field.settings.language_fallback'
|
||||
* variable to FALSE.
|
||||
*
|
||||
* @param $field_langcodes
|
||||
* A reference to an array of language codes keyed by field name.
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity to be displayed.
|
||||
* @param $langcode
|
||||
* The language code $entity has to be displayed in.
|
||||
*/
|
||||
function field_language_fallback(&$field_langcodes, EntityInterface $entity, $langcode) {
|
||||
// Lazily init fallback candidates to avoid unnecessary calls.
|
||||
$fallback_candidates = NULL;
|
||||
|
||||
foreach ($field_langcodes as $field_name => $field_langcode) {
|
||||
// If the requested language is defined for the current field use it,
|
||||
// otherwise search for a fallback value among the fallback candidates.
|
||||
if (_field_translated_value_exists($entity, $langcode, $field_name)) {
|
||||
$field_langcodes[$field_name] = $langcode;
|
||||
}
|
||||
else {
|
||||
if (!isset($fallback_candidates)) {
|
||||
require_once DRUPAL_ROOT . '/core/includes/language.inc';
|
||||
$fallback_candidates = language_fallback_get_candidates();
|
||||
}
|
||||
foreach ($fallback_candidates as $fallback_langcode) {
|
||||
if (_field_translated_value_exists($entity, $fallback_langcode, $field_name)) {
|
||||
$field_langcodes[$field_name] = $fallback_langcode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the available language codes for the given entity type and field.
|
||||
*
|
||||
|
@ -195,13 +152,6 @@ function field_content_languages() {
|
|||
return array_keys(language_list(Language::STATE_ALL));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether field language fallback is enabled.
|
||||
*/
|
||||
function field_language_fallback_enabled() {
|
||||
return language_multilingual() && \Drupal::config('field.settings')->get('language_fallback');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a field has language support.
|
||||
*
|
||||
|
@ -242,126 +192,3 @@ function field_has_translation_handler($entity_type, $handler = NULL) {
|
|||
$info = entity_get_info($entity_type);
|
||||
return !empty($info['translatable']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that a given language code is valid.
|
||||
*
|
||||
* Checks whether the given language code is one of the enabled language codes.
|
||||
* Otherwise, it returns the current, global language code; or the site's
|
||||
* default language code, if the additional parameter $default is TRUE.
|
||||
*
|
||||
* @param $langcode
|
||||
* The language code to validate.
|
||||
* @param $default
|
||||
* Whether to return the default language code or the current language code in
|
||||
* case $langcode is invalid.
|
||||
*
|
||||
* @return
|
||||
* A valid language code.
|
||||
*/
|
||||
function field_valid_language($langcode, $default = TRUE) {
|
||||
$languages = field_content_languages();
|
||||
if (in_array($langcode, $languages)) {
|
||||
return $langcode;
|
||||
}
|
||||
return $default ? language_default()->id : language(Language::TYPE_CONTENT)->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the display language code for the fields attached to the given
|
||||
* entity.
|
||||
*
|
||||
* The actual language code for each given field is determined based on the
|
||||
* requested language code and the actual data available in the fields
|
||||
* themselves.
|
||||
* If there is no registered translation handler for the given entity type, the
|
||||
* display language code to be used is just Language::LANGCODE_NOT_SPECIFIED, as no other
|
||||
* language code is allowed by field_available_languages().
|
||||
*
|
||||
* If translation handlers are found, we let modules provide alternative display
|
||||
* language codes for fields not having the requested language code available.
|
||||
* Core language fallback rules are provided by field_language_fallback()
|
||||
* which is called by field_field_language_alter().
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity to be displayed.
|
||||
* @param $field_name
|
||||
* (optional) The name of the field to be displayed. Defaults to NULL. If
|
||||
* no value is specified, the display language codes for every field attached
|
||||
* to the given entity will be returned.
|
||||
* @param $langcode
|
||||
* (optional) The language code $entity has to be displayed in. Defaults to
|
||||
* NULL. If no value is given the current language will be used.
|
||||
*
|
||||
* @return
|
||||
* A language code if a field name is specified, an array of language codes
|
||||
* keyed by field name otherwise.
|
||||
*/
|
||||
function field_language(EntityInterface $entity, $displayed_field_name = NULL, $langcode = NULL) {
|
||||
$display_langcodes = &drupal_static(__FUNCTION__, array());
|
||||
$id = $entity->id();
|
||||
$bundle = $entity->bundle();
|
||||
$entity_type = $entity->entityType();
|
||||
$langcode = field_valid_language($langcode, FALSE);
|
||||
if (!isset($display_langcodes[$entity_type][$id][$langcode])) {
|
||||
$display_langcode = array();
|
||||
|
||||
// By default, display language is set to one of the locked languages
|
||||
// if the field translation is not available. It is up to translation
|
||||
// handlers to implement language fallback rules.
|
||||
foreach (field_info_instances($entity_type, $bundle) as $field_name => $instance) {
|
||||
if (_field_translated_value_exists($entity, $langcode, $field_name)) {
|
||||
$display_langcode[$field_name] = $langcode;
|
||||
}
|
||||
else {
|
||||
// If the field has a value for one of the locked languages, then use
|
||||
// that language for display. If not, the default one will be
|
||||
// Language::LANGCODE_NOT_SPECIFIED.
|
||||
$display_langcode[$field_name] = Language::LANGCODE_NOT_SPECIFIED;
|
||||
foreach (language_list(Language::STATE_LOCKED) as $language_locked) {
|
||||
if (isset($entity->{$field_name}[$language_locked->id])) {
|
||||
$display_langcode[$field_name] = $language_locked->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (field_has_translation_handler($entity_type)) {
|
||||
$context = array(
|
||||
'entity' => $entity,
|
||||
'langcode' => $langcode,
|
||||
);
|
||||
// Do not apply core language fallback rules if they are disabled or if
|
||||
// the entity does not have a translation handler registered.
|
||||
if (field_language_fallback_enabled() && field_has_translation_handler($entity_type)) {
|
||||
field_language_fallback($display_langcode, $context['entity'], $context['langcode']);
|
||||
}
|
||||
drupal_alter('field_language', $display_langcode, $context);
|
||||
}
|
||||
|
||||
$display_langcodes[$entity_type][$id][$langcode] = $display_langcode;
|
||||
}
|
||||
|
||||
$display_langcode = $display_langcodes[$entity_type][$id][$langcode];
|
||||
|
||||
// Single-field mode.
|
||||
if (isset($displayed_field_name)) {
|
||||
return isset($display_langcode[$displayed_field_name]) ? $display_langcode[$displayed_field_name] : FALSE;
|
||||
}
|
||||
|
||||
return $display_langcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if a non-empty value exists for a given entity/language/field.
|
||||
*/
|
||||
function _field_translated_value_exists(EntityInterface $entity, $langcode, $field_name) {
|
||||
if (!$entity->hasTranslation($langcode)) {
|
||||
return FALSE;
|
||||
}
|
||||
$field = $entity->getTranslation($langcode)->$field_name;
|
||||
$field->filterEmptyValues();
|
||||
$value = $field->getValue();
|
||||
return !empty($value);
|
||||
}
|
||||
|
|
|
@ -263,14 +263,7 @@ class Field extends FieldPluginBase {
|
|||
$this->view->display_handler->options['field_langcode']
|
||||
);
|
||||
$placeholder = $this->placeholder();
|
||||
$langcode_fallback_candidates = array($langcode);
|
||||
if (field_language_fallback_enabled()) {
|
||||
require_once DRUPAL_ROOT . '/includes/language.inc';
|
||||
$langcode_fallback_candidates = array_merge($langcode_fallback_candidates, language_fallback_get_candidates());
|
||||
}
|
||||
else {
|
||||
$langcode_fallback_candidates[] = Language::LANGCODE_NOT_SPECIFIED;
|
||||
}
|
||||
$langcode_fallback_candidates = $this->languageManager->getFallbackCandidates($langcode, array('operation' => 'views_query', 'data' => $this));
|
||||
$this->query->addWhereExpression(0, "$column IN($placeholder) OR $column IS NULL", array($placeholder => $langcode_fallback_candidates));
|
||||
}
|
||||
}
|
||||
|
@ -870,11 +863,12 @@ class Field extends FieldPluginBase {
|
|||
$this->view->display_handler->options['field_language']
|
||||
);
|
||||
|
||||
// Give the Field Language API a chance to fallback to a different language
|
||||
// (or Language::LANGCODE_NOT_SPECIFIED), in case the field has no data for the selected language.
|
||||
// field_view_field() does this as well, but since the returned language code
|
||||
// is used before calling it, the fallback needs to happen explicitly.
|
||||
$langcode = field_language($entity, $this->field_info['field_name'], $langcode);
|
||||
// Give the Entity Field API a chance to fallback to a different language
|
||||
// (or Language::LANGCODE_NOT_SPECIFIED), in case the field has no data
|
||||
// for the selected language. field_view_field() does this as well, but
|
||||
// since the returned language code is used before calling it, the
|
||||
// fallback needs to happen explicitly.
|
||||
$langcode = $this->entityManager->getTranslationFromContext($entity, $langcode)->language()->id;
|
||||
|
||||
return $langcode;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,8 @@ class TranslationTest extends FieldUnitTestBase {
|
|||
function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installConfig(array('language'));
|
||||
|
||||
$this->field_name = drupal_strtolower($this->randomName() . '_field_name');
|
||||
|
||||
$this->entity_type = 'entity_test';
|
||||
|
@ -159,6 +161,7 @@ class TranslationTest extends FieldUnitTestBase {
|
|||
$field_translations = array();
|
||||
$available_langcodes = field_available_languages($entity_type, $this->field);
|
||||
$this->assertTrue(count($available_langcodes) > 1, 'Field is translatable.');
|
||||
$available_langcodes = array_keys(language_list());
|
||||
$entity->langcode->value = reset($available_langcodes);
|
||||
foreach ($available_langcodes as $langcode) {
|
||||
$field_translations[$langcode] = $this->_generateTestFieldValues($this->field->getFieldCardinality());
|
||||
|
@ -228,100 +231,4 @@ class TranslationTest extends FieldUnitTestBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests display language logic for translatable fields.
|
||||
*/
|
||||
function testFieldDisplayLanguage() {
|
||||
$field_name = drupal_strtolower($this->randomName() . '_field_name');
|
||||
$entity_type = 'entity_test';
|
||||
$bundle = 'entity_test';
|
||||
|
||||
// We need an additional field here to properly test display language
|
||||
// suggestions.
|
||||
$field = array(
|
||||
'name' => $field_name,
|
||||
'entity_type' => $entity_type,
|
||||
'type' => 'test_field',
|
||||
'cardinality' => 2,
|
||||
'translatable' => TRUE,
|
||||
);
|
||||
entity_create('field_entity', $field)->save();
|
||||
|
||||
$instance = array(
|
||||
'field_name' => $field['name'],
|
||||
'entity_type' => $entity_type,
|
||||
'bundle' => $bundle,
|
||||
);
|
||||
entity_create('field_instance', $instance)->save();
|
||||
|
||||
$enabled_langcodes = field_content_languages();
|
||||
$entity = entity_create($entity_type, array('id' => 1, 'revision_id' => 1, 'type' => $this->instance->bundle));;
|
||||
$entity->langcode->value = reset($enabled_langcodes);
|
||||
$instances = field_info_instances($entity_type, $bundle);
|
||||
|
||||
$langcodes = array();
|
||||
// This array is used to store, for each field name, which one of the locked
|
||||
// languages will be used for display.
|
||||
$locked_languages = array();
|
||||
|
||||
// Generate field translations for languages different from the first
|
||||
// enabled.
|
||||
foreach ($instances as $instance) {
|
||||
$field_name = $instance->getFieldName();
|
||||
$field = $instance->getField();
|
||||
do {
|
||||
// Index 0 is reserved for the requested language, this way we ensure
|
||||
// that no field is actually populated with it.
|
||||
$langcode = $enabled_langcodes[mt_rand(1, count($enabled_langcodes) - 1)];
|
||||
}
|
||||
while (isset($langcodes[$langcode]));
|
||||
$langcodes[$langcode] = TRUE;
|
||||
$entity->getTranslation($langcode)->{$field_name}->setValue($this->_generateTestFieldValues($field->getFieldCardinality()));
|
||||
// If the langcode is one of the locked languages, then that one
|
||||
// will also be used for display. Otherwise, the default one should be
|
||||
// used, which is Language::LANGCODE_NOT_SPECIFIED.
|
||||
if (language_is_locked($langcode)) {
|
||||
$locked_languages[$field_name] = $langcode;
|
||||
}
|
||||
else {
|
||||
$locked_languages[$field_name] = Language::LANGCODE_NOT_SPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
// Test multiple-fields display languages for untranslatable entities.
|
||||
field_test_entity_info_translatable($entity_type, FALSE);
|
||||
drupal_static_reset('field_language');
|
||||
$requested_langcode = $enabled_langcodes[0];
|
||||
$display_langcodes = field_language($entity, NULL, $requested_langcode);
|
||||
foreach ($instances as $instance) {
|
||||
$field_name = $instance->getFieldName();
|
||||
$this->assertTrue($display_langcodes[$field_name] == $locked_languages[$field_name], format_string('The display language for field %field_name is %language.', array('%field_name' => $field_name, '%language' => $locked_languages[$field_name])));
|
||||
}
|
||||
|
||||
// Test multiple-fields display languages for translatable entities.
|
||||
field_test_entity_info_translatable($entity_type, TRUE);
|
||||
drupal_static_reset('field_language');
|
||||
$display_langcodes = field_language($entity, NULL, $requested_langcode);
|
||||
foreach ($instances as $instance) {
|
||||
$field_name = $instance->getFieldName();
|
||||
$langcode = $display_langcodes[$field_name];
|
||||
// As the requested language was not assinged to any field, if the
|
||||
// returned language is defined for the current field, core fallback rules
|
||||
// were successfully applied.
|
||||
$this->assertTrue(!empty($entity->getTranslation($langcode)->{$field_name}) && $langcode != $requested_langcode, format_string('The display language for the field %field_name is %language.', array('%field_name' => $field_name, '%language' => $langcode)));
|
||||
}
|
||||
|
||||
// Test single-field display language.
|
||||
drupal_static_reset('field_language');
|
||||
$langcode = field_language($entity, $this->field_name, $requested_langcode);
|
||||
$this->assertTrue(!empty($entity->getTranslation($langcode)->{$this->field_name}) && $langcode != $requested_langcode, format_string('The display language for the (single) field %field_name is %language.', array('%field_name' => $field_name, '%language' => $langcode)));
|
||||
|
||||
// Test field_language() basic behavior without language fallback.
|
||||
\Drupal::state()->set('field_test.language_fallback', FALSE);
|
||||
$entity->getTranslation($requested_langcode)->{$this->field_name}->value = mt_rand(1, 127);
|
||||
drupal_static_reset('field_language');
|
||||
$display_langcode = field_language($entity, $this->field_name, $requested_langcode);
|
||||
$this->assertEqual($display_langcode, $requested_langcode, 'Display language behave correctly when language fallback is disabled');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -109,6 +109,7 @@ class TranslationWebTest extends FieldTestBase {
|
|||
$field_name = $this->field->getFieldName();
|
||||
|
||||
// Store the field translations.
|
||||
ksort($available_langcodes);
|
||||
$entity->langcode->value = key($available_langcodes);
|
||||
foreach ($available_langcodes as $langcode => $value) {
|
||||
$entity->getTranslation($langcode)->{$field_name}->value = $value + 1;
|
||||
|
|
|
@ -62,15 +62,6 @@ function field_test_field_available_languages_alter(&$langcodes, $context) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_language_alter().
|
||||
*/
|
||||
function field_test_field_language_alter(&$display_langcode, $context) {
|
||||
if (\Drupal::state()->get('field_test.language_fallback') ?: TRUE) {
|
||||
field_language_fallback($display_langcode, $context['entity'], $context['langcode']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store and retrieve keyed data for later verification by unit tests.
|
||||
*
|
||||
|
|
|
@ -8,11 +8,7 @@
|
|||
namespace Drupal\forum\Form;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Config\ConfigFactory;
|
||||
use Drupal\taxonomy\TermFormController;
|
||||
use Drupal\taxonomy\TermStorageControllerInterface;
|
||||
use Drupal\taxonomy\VocabularyStorageControllerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Base form controller for forum term edit forms.
|
||||
|
@ -33,47 +29,6 @@ class ForumFormController extends TermFormController {
|
|||
*/
|
||||
protected $urlStub = 'forum';
|
||||
|
||||
/**
|
||||
* The forum config.
|
||||
*
|
||||
* @var \Drupal\Core\Config\Config
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Term Storage Controller.
|
||||
*
|
||||
* @var \Drupal\taxonomy\TermStorageControllerInterface
|
||||
*/
|
||||
protected $termStorage;
|
||||
|
||||
/**
|
||||
* Constructs a new ForumFormController object.
|
||||
*
|
||||
* @param \Drupal\taxonomy\VocabularyStorageControllerInterface $vocab_storage
|
||||
* The vocabulary storage.
|
||||
* @param \Drupal\Core\Config\ConfigFactory $config_factory
|
||||
* The config factory service.
|
||||
* @param \Drupal\taxonomy\TermStorageControllerInterface $term_storage
|
||||
* The term storage.
|
||||
*/
|
||||
public function __construct(VocabularyStorageControllerInterface $vocab_storage, ConfigFactory $config_factory, TermStorageControllerInterface $term_storage) {
|
||||
parent::__construct($vocab_storage, $config_factory);
|
||||
$this->termStorage = $term_storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
$entity_manager = $container->get('entity.manager');
|
||||
return new static(
|
||||
$entity_manager->getStorageController('taxonomy_vocabulary'),
|
||||
$container->get('config.factory'),
|
||||
$entity_manager->getStorageController('taxonomy_term')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -121,8 +76,9 @@ class ForumFormController extends TermFormController {
|
|||
*/
|
||||
public function save(array $form, array &$form_state) {
|
||||
$term = $this->entity;
|
||||
$term_storage = $this->entityManager->getStorageController('taxonomy_term');
|
||||
$status = $term_storage->save($term);
|
||||
|
||||
$status = $this->termStorage->save($term);
|
||||
switch ($status) {
|
||||
case SAVED_NEW:
|
||||
drupal_set_message($this->t('Created new @type %term.', array('%term' => $term->label(), '@type' => $this->forumFormType)));
|
||||
|
|
|
@ -57,6 +57,40 @@ function hook_language_delete($language) {
|
|||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow modules to alter the language fallback candidates.
|
||||
*
|
||||
* @param array $candidates
|
||||
* An array of language codes whose order will determine the language fallback
|
||||
* order.
|
||||
* @param array $context
|
||||
* A language fallback context.
|
||||
*
|
||||
* @see \Drupal\Core\Language\LanguageManager::getFallbackCandidates()
|
||||
*/
|
||||
function hook_language_fallback_candidates_alter(array &$candidates, array $context) {
|
||||
$candidates = array_reverse($candidates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow modules to alter the fallback candidates for specific operations.
|
||||
*
|
||||
* @param array $candidates
|
||||
* An array of language codes whose order will determine the language fallback
|
||||
* order.
|
||||
* @param array $context
|
||||
* A language fallback context.
|
||||
*
|
||||
* @see \Drupal\Core\Language\LanguageManager::getFallbackCandidates()
|
||||
*/
|
||||
function hook_language_fallback_candidates_OPERATION_alter(array &$candidates, array $context) {
|
||||
// We know that the current OPERATION deals with entities so no need to check
|
||||
// here.
|
||||
if ($context['data']->entityType() == 'node') {
|
||||
$candidates = array_reverse($candidates);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "addtogroup hooks".
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\language\Tests\LanguageFallbackTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\language\Tests;
|
||||
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\simpletest\DrupalUnitTestBase;
|
||||
|
||||
/**
|
||||
* Tests the language fallback behavior.
|
||||
*/
|
||||
class LanguageFallbackTest extends DrupalUnitTestBase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Language fallback',
|
||||
'description' => 'Tests the language fallback behavior.',
|
||||
'group' => 'Language',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The state storage service.
|
||||
*
|
||||
* @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->enableModules(array('language', 'language_test'));
|
||||
$this->installConfig(array('language'));
|
||||
|
||||
$this->state = $this->container->get('state');
|
||||
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$language = new Language();
|
||||
$language->id = $this->randomName(2);
|
||||
$language->weight = -$i;
|
||||
language_save($language);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests language fallback candidates.
|
||||
*/
|
||||
public function testCandidates() {
|
||||
$manager = $this->getLanguageManager();
|
||||
$expected = array_keys(language_list() + array(Language::LANGCODE_NOT_SPECIFIED => NULL));
|
||||
|
||||
// Check that language fallback candidates by default are all the available
|
||||
// languages sorted by weight.
|
||||
$candidates = $manager->getFallbackCandidates();
|
||||
$this->assertEqual(array_values($candidates), $expected, 'Language fallback candidates are properly returned.');
|
||||
|
||||
// Check that candidates are alterable.
|
||||
$this->state->set('language_test.fallback_alter.candidates', TRUE);
|
||||
$expected = array_slice($expected, 0, count($expected) - 1);
|
||||
$candidates = $manager->getFallbackCandidates();
|
||||
$this->assertEqual(array_values($candidates), $expected, 'Language fallback candidates are alterable.');
|
||||
|
||||
// Check that candidates are alterable for specific operations.
|
||||
$this->state->set('language_test.fallback_alter.candidates', FALSE);
|
||||
$this->state->set('language_test.fallback_operation_alter.candidates', TRUE);
|
||||
$expected[] = Language::LANGCODE_NOT_SPECIFIED;
|
||||
$expected[] = Language::LANGCODE_NOT_APPLICABLE;
|
||||
$candidates = $manager->getFallbackCandidates(NULL, array('operation' => 'test'));
|
||||
$this->assertEqual(array_values($candidates), $expected, 'Language fallback candidates are alterable for specific operations.');
|
||||
|
||||
// Check that when the site is monolingual no language fallback is applied.
|
||||
$default_langcode = language_default()->id;
|
||||
foreach (language_list() as $langcode => $language) {
|
||||
if ($langcode != $default_langcode) {
|
||||
language_delete($langcode);
|
||||
}
|
||||
}
|
||||
$candidates = $this->getLanguageManager()->getFallbackCandidates();
|
||||
$this->assertEqual(array_values($candidates), array(Language::LANGCODE_DEFAULT), 'Language fallback is not applied when the Language module is not enabled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language manager service.
|
||||
*
|
||||
* @return \Drupal\Core\Language\LanguageManager
|
||||
* The language manager.
|
||||
*/
|
||||
protected function getLanguageManager() {
|
||||
return $this->container->get('language_manager');
|
||||
}
|
||||
|
||||
}
|
|
@ -109,3 +109,22 @@ function language_test_store_language_negotiation() {
|
|||
function language_test_language_negotiation_method($languages) {
|
||||
return 'it';
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_language_fallback_candidates_alter().
|
||||
*/
|
||||
function language_test_language_fallback_candidates_alter(array &$candidates, array $context) {
|
||||
if (Drupal::state()->get('language_test.fallback_alter.candidates')) {
|
||||
unset($candidates[Language::LANGCODE_NOT_SPECIFIED]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_language_fallback_candidates_OPERATION_alter().
|
||||
*/
|
||||
function language_test_language_fallback_candidates_test_alter(array &$candidates, array $context) {
|
||||
if (Drupal::state()->get('language_test.fallback_operation_alter.candidates')) {
|
||||
$langcode = Language::LANGCODE_NOT_APPLICABLE;
|
||||
$candidates[$langcode] = $langcode;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -964,6 +964,15 @@ function locale_update_8017() {
|
|||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the field language fallback settings as it is no longer supported.
|
||||
*
|
||||
* @ingroup config_upgrade
|
||||
*/
|
||||
function locale_update_8018() {
|
||||
update_variable_del('locale_field_language_fallback');
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "addtogroup updates-7.x-to-8.x".
|
||||
* The next series of updates should start at 9000.
|
||||
|
|
|
@ -127,7 +127,7 @@ class NodeController extends ControllerBase {
|
|||
* The page title.
|
||||
*/
|
||||
public function pageTitle(NodeInterface $node) {
|
||||
return String::checkPlain($node->label());
|
||||
return String::checkPlain($this->entityManager()->getTranslationFromContext($node)->label());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace Drupal\node\Form;
|
|||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Entity\ContentEntityConfirmFormBase;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Routing\UrlGeneratorInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
|
@ -25,24 +25,17 @@ class NodeDeleteForm extends ContentEntityConfirmFormBase {
|
|||
*/
|
||||
protected $urlGenerator;
|
||||
|
||||
/**
|
||||
* The node type storage.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityStorageControllerInterface
|
||||
*/
|
||||
protected $nodeTypeStorage;
|
||||
|
||||
/**
|
||||
* Constructs a NodeDeleteForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
|
||||
* The URL generator.
|
||||
* @param \Drupal\Core\Entity\EntityStorageControllerInterface $node_type_storage
|
||||
* The node type storage.
|
||||
*/
|
||||
public function __construct(UrlGeneratorInterface $url_generator, EntityStorageControllerInterface $node_type_storage) {
|
||||
public function __construct(EntityManagerInterface $entity_manager, UrlGeneratorInterface $url_generator) {
|
||||
parent::__construct($entity_manager);
|
||||
$this->urlGenerator = $url_generator;
|
||||
$this->nodeTypeStorage = $node_type_storage;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -50,8 +43,8 @@ class NodeDeleteForm extends ContentEntityConfirmFormBase {
|
|||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('url_generator'),
|
||||
$container->get('entity.manager')->getStorageController('node_type')
|
||||
$container->get('entity.manager'),
|
||||
$container->get('url_generator')
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -94,7 +87,8 @@ class NodeDeleteForm extends ContentEntityConfirmFormBase {
|
|||
public function submit(array $form, array &$form_state) {
|
||||
$this->entity->delete();
|
||||
watchdog('content', '@type: deleted %title.', array('@type' => $this->entity->bundle(), '%title' => $this->entity->label()));
|
||||
$node_type = $this->nodeTypeStorage->load($this->entity->bundle())->label();
|
||||
$node_type_storage = $this->entityManager->getStorageController('node_type');
|
||||
$node_type = $node_type_storage->load($this->entity->bundle())->label();
|
||||
drupal_set_message(t('@type %title has been deleted.', array('@type' => $node_type, '%title' => $this->entity->label())));
|
||||
Cache::invalidateTags(array('content' => TRUE));
|
||||
$form_state['redirect'] = '<front>';
|
||||
|
|
|
@ -72,7 +72,7 @@ class NodeTranslationUITest extends ContentTranslationUITest {
|
|||
/**
|
||||
* Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::assertPublishedStatus().
|
||||
*/
|
||||
protected function assertPublishedStatus() {
|
||||
protected function doTestPublishedStatus() {
|
||||
$entity = entity_load($this->entityType, $this->entityId, TRUE);
|
||||
$path = $this->controller->getEditPath($entity);
|
||||
$languages = language_list();
|
||||
|
@ -104,7 +104,7 @@ class NodeTranslationUITest extends ContentTranslationUITest {
|
|||
/**
|
||||
* Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::assertAuthoringInfo().
|
||||
*/
|
||||
protected function assertAuthoringInfo() {
|
||||
protected function doTestAuthoringInfo() {
|
||||
$entity = entity_load($this->entityType, $this->entityId, TRUE);
|
||||
$path = $this->controller->getEditPath($entity);
|
||||
$languages = language_list();
|
||||
|
@ -188,4 +188,47 @@ class NodeTranslationUITest extends ContentTranslationUITest {
|
|||
$this->assertEqual($enabledNode->id(), reset($rows)->entity_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that translations are rendered properly.
|
||||
*/
|
||||
function testTranslationRendering() {
|
||||
$default_langcode = $this->langcodes[0];
|
||||
$values[$default_langcode] = $this->getNewEntityValues($default_langcode);
|
||||
$this->entityId = $this->createEntity($values[$default_langcode], $default_langcode);
|
||||
$node = \Drupal::entityManager()->getStorageController($this->entityType)->load($this->entityId);
|
||||
$node->setPromoted(TRUE);
|
||||
|
||||
// Create translations.
|
||||
foreach (array_diff($this->langcodes, array($default_langcode)) as $langcode) {
|
||||
$values[$langcode] = $this->getNewEntityValues($langcode);
|
||||
$translation = $node->addTranslation($langcode, $values[$langcode]);
|
||||
$translation->setPromoted(TRUE);
|
||||
}
|
||||
$node->save();
|
||||
|
||||
// Test that the frontpage view displays the correct translations.
|
||||
\Drupal::moduleHandler()->install(array('views'), TRUE);
|
||||
$this->rebuildContainer();
|
||||
$this->doTestTranslations('node', $values);
|
||||
|
||||
// Test that the node page displays the correct translations.
|
||||
$this->doTestTranslations('node/' . $node->id(), $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the given path dsiplays the correct translation values.
|
||||
*
|
||||
* @param string $path
|
||||
* The path to be tested.
|
||||
* @param array $values
|
||||
* The translation values to be found.
|
||||
*/
|
||||
protected function doTestTranslations($path, array $values) {
|
||||
$languages = language_list();
|
||||
foreach ($this->langcodes as $langcode) {
|
||||
$this->drupalGet($path, array('language' => $languages[$langcode]));
|
||||
$this->assertText($values[$langcode]['title'], format_string('The %langcode node translation is correctly displayed.', array('%langcode' => $langcode)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -129,11 +129,11 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
|
|||
|
||||
case 'body':
|
||||
case 'summary':
|
||||
if (($items = $node->getTranslation($langcode)->get('body')) && !$items->isEmpty()) {
|
||||
$translation = \Drupal::entityManager()->getTranslationFromContext($node, $langcode, array('operation' => 'node_tokens'));
|
||||
if (($items = $translation->get('body')) && !$items->isEmpty()) {
|
||||
$item = $items[0];
|
||||
$instance = field_info_instance('node', 'body', $node->getType());
|
||||
$field_langcode = field_language($node, 'body', $langcode);
|
||||
|
||||
$field_langcode = $translation->language()->id;
|
||||
// If the summary was requested and is not empty, use it.
|
||||
if ($name == 'summary' && !empty($item->summary)) {
|
||||
$output = $sanitize ? $item->summary_processed : $item->summary;
|
||||
|
|
|
@ -151,17 +151,6 @@ function hook_language_negotiation_info_alter(array &$negotiation_info) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform alterations on the language fallback candidates.
|
||||
*
|
||||
* @param $fallback_candidates
|
||||
* An array of language codes whose order will determine the language fallback
|
||||
* order.
|
||||
*/
|
||||
function hook_language_fallback_candidates_alter(array &$fallback_candidates) {
|
||||
$fallback_candidates = array_reverse($fallback_candidates);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "addtogroup hooks".
|
||||
*/
|
||||
|
|
|
@ -34,7 +34,7 @@ class EntityManagerTest extends EntityUnitTestBase {
|
|||
$this->assertFalse($entity_manager->hasController('non_existent', 'non_existent'), 'A non existent entity type has no controller.');
|
||||
|
||||
$this->assertFalse($entity_manager->hasController('entity_test', 'non_existent'), 'An existent entity type does not have a non existent controller.');
|
||||
$this->assertFalse($entity_manager->hasController('entity_test_mul', 'view_builder'), 'The test entity does not have specified the view builder.');
|
||||
$this->assertFalse($entity_manager->hasController('entity_test_mulrev', 'view_builder'), 'The test entity does not have specified the view builder.');
|
||||
|
||||
$this->assertTrue($entity_manager->hasController('entity_test', 'storage'), 'The test entity has specified the controller class');
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace Drupal\system\Tests\Entity;
|
|||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\TypedData\TranslatableInterface;
|
||||
use Drupal\entity_test\Entity\EntityTestMulRev;
|
||||
use Drupal\Component\Utility\MapArray;
|
||||
|
||||
/**
|
||||
* Tests entity translation.
|
||||
|
@ -83,6 +84,7 @@ class EntityTranslationTest extends EntityUnitTestBase {
|
|||
$language = new Language(array(
|
||||
'id' => 'l' . $i,
|
||||
'name' => $this->randomString(),
|
||||
'weight' => $i,
|
||||
));
|
||||
$this->langcodes[$i] = $language->id;
|
||||
language_save($language);
|
||||
|
@ -493,6 +495,69 @@ class EntityTranslationTest extends EntityUnitTestBase {
|
|||
$this->assertEqual($field->getLangcode(), $langcode2, 'Field object has the expected langcode.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests language fallback applied to field and entity translations.
|
||||
*/
|
||||
function testLanguageFallback() {
|
||||
$current_langcode = $this->container->get('language_manager')->getLanguage(Language::TYPE_CONTENT)->id;
|
||||
$this->langcodes[] = $current_langcode;
|
||||
|
||||
$values = array();
|
||||
foreach ($this->langcodes as $langcode) {
|
||||
$values[$langcode]['name'] = $this->randomName();
|
||||
$values[$langcode]['user_id'] = mt_rand(0, 127);
|
||||
}
|
||||
|
||||
$default_langcode = $this->langcodes[0];
|
||||
$langcode = $this->langcodes[1];
|
||||
$langcode2 = $this->langcodes[2];
|
||||
|
||||
$entity_type = 'entity_test_mul';
|
||||
$controller = $this->entityManager->getStorageController($entity_type);
|
||||
$entity = $controller->create(array('langcode' => $default_langcode) + $values[$default_langcode]);
|
||||
$entity->save();
|
||||
|
||||
$entity->addTranslation($langcode, $values[$langcode]);
|
||||
$entity->save();
|
||||
|
||||
// Check that retrieveing the current translation works as expected.
|
||||
$entity = $this->reloadEntity($entity);
|
||||
$translation = $this->entityManager->getTranslationFromContext($entity, $langcode2);
|
||||
$this->assertEqual($translation->language()->id, $default_langcode, 'The current translation language matches the expected one.');
|
||||
|
||||
// Check that language fallback respects language weight by default.
|
||||
$languages = language_list();
|
||||
$languages[$langcode]->weight = -1;
|
||||
language_save($languages[$langcode]);
|
||||
$translation = $this->entityManager->getTranslationFromContext($entity, $langcode2);
|
||||
$this->assertEqual($translation->language()->id, $langcode, 'The current translation language matches the expected one.');
|
||||
|
||||
// Check that the current translation is properly returned.
|
||||
$translation = $this->entityManager->getTranslationFromContext($entity);
|
||||
$this->assertEqual($langcode, $translation->language()->id, 'The current translation language matches the topmost language fallback candidate.');
|
||||
$entity->addTranslation($current_langcode, $values[$current_langcode]);
|
||||
$translation = $this->entityManager->getTranslationFromContext($entity);
|
||||
$this->assertEqual($current_langcode, $translation->language()->id, 'The current translation language matches the current language.');
|
||||
|
||||
// Check that if the entity has no translation no fallback is applied.
|
||||
$entity2 = $controller->create(array('langcode' => $default_langcode));
|
||||
$translation = $this->entityManager->getTranslationFromContext($entity2, $default_langcode);
|
||||
$this->assertIdentical($entity2, $translation, 'When the entity has no translation no fallback is applied.');
|
||||
|
||||
// Checks that entity translations are rendered properly.
|
||||
$controller = $this->entityManager->getViewBuilder($entity_type);
|
||||
$build = $controller->view($entity);
|
||||
$this->assertEqual($build['label']['#markup'], $values[$current_langcode]['name'], 'By default the entity is rendered in the current language.');
|
||||
$langcodes = MapArray::copyValuesToKeys($this->langcodes);
|
||||
// We have no translation for the $langcode2 langauge, hence the expected
|
||||
// result is the topmost existing translation, that is $langcode.
|
||||
$langcodes[$langcode2] = $langcode;
|
||||
foreach ($langcodes as $desired => $expected) {
|
||||
$build = $controller->view($entity, 'full', $desired);
|
||||
$this->assertEqual($build['label']['#markup'], $values[$expected]['name'], 'The entity is rendered in the expected language.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that field translatability is handled properly.
|
||||
*/
|
||||
|
|
|
@ -98,8 +98,11 @@ class EntityTest extends ContentEntityBase {
|
|||
/**
|
||||
* Overrides Drupal\entity\Entity::label().
|
||||
*/
|
||||
public function label($langcode = Language::LANGCODE_DEFAULT) {
|
||||
public function label($langcode = NULL) {
|
||||
$info = $this->entityInfo();
|
||||
if (!isset($langcode)) {
|
||||
$langcode = $this->activeLangcode;
|
||||
}
|
||||
if (isset($info['entity_keys']['label']) && $info['entity_keys']['label'] == 'name') {
|
||||
return $this->getTranslation($langcode)->name->value;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ use Drupal\Core\Annotation\Translation;
|
|||
* label = @Translation("Test entity - data table"),
|
||||
* controllers = {
|
||||
* "storage" = "Drupal\entity_test\EntityTestStorageController",
|
||||
* "view_builder" = "Drupal\entity_test\EntityTestViewBuilder",
|
||||
* "access" = "Drupal\entity_test\EntityTestAccessController",
|
||||
* "form" = {
|
||||
* "default" = "Drupal\entity_test\EntityTestFormController"
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
namespace Drupal\taxonomy\Form;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\taxonomy\VocabularyStorageControllerInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\ContentEntityConfirmFormBase;
|
||||
use Drupal\Core\Cache\Cache;
|
||||
|
||||
|
@ -17,32 +17,6 @@ use Drupal\Core\Cache\Cache;
|
|||
*/
|
||||
class TermDeleteForm extends ContentEntityConfirmFormBase {
|
||||
|
||||
/**
|
||||
* The taxonomy vocabulary storage controller.
|
||||
*
|
||||
* @var \Drupal\taxonomy\VocabularyStorageControllerInterface
|
||||
*/
|
||||
protected $vocabularyStorageController;
|
||||
|
||||
/**
|
||||
* Constructs a new TermDelete object.
|
||||
*
|
||||
* @param \Drupal\taxonomy\VocabularyStorageControllerInterface $storage_controller
|
||||
* The Entity manager.
|
||||
*/
|
||||
public function __construct(VocabularyStorageControllerInterface $storage_controller) {
|
||||
$this->vocabularyStorageController = $storage_controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager')->getStorageController('taxonomy_vocabulary')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -85,7 +59,8 @@ class TermDeleteForm extends ContentEntityConfirmFormBase {
|
|||
*/
|
||||
public function submit(array $form, array &$form_state) {
|
||||
$this->entity->delete();
|
||||
$vocabulary = $this->vocabularyStorageController->load($this->entity->bundle());
|
||||
$storage_controller = $this->entityManager->getStorageController('taxonomy_vocabulary');
|
||||
$vocabulary = $storage_controller->load($this->entity->bundle());
|
||||
|
||||
// @todo Move to storage controller http://drupal.org/node/1988712
|
||||
taxonomy_check_vocabulary_hierarchy($vocabulary, array('tid' => $this->entity->id()));
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace Drupal\taxonomy;
|
|||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Config\ConfigFactory;
|
||||
use Drupal\Core\Entity\ContentEntityFormController;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
|
@ -18,13 +19,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
*/
|
||||
class TermFormController extends ContentEntityFormController {
|
||||
|
||||
/**
|
||||
* The vocabulary storage.
|
||||
*
|
||||
* @var \Drupal\taxonomy\VocabularyStorageControllerInterface
|
||||
*/
|
||||
protected $vocabStorage;
|
||||
|
||||
/**
|
||||
* The config factory.
|
||||
*
|
||||
|
@ -35,13 +29,13 @@ class TermFormController extends ContentEntityFormController {
|
|||
/**
|
||||
* Constructs a new TermFormController.
|
||||
*
|
||||
* @param \Drupal\taxonomy\VocabularyStorageControllerInterface $vocab_storage
|
||||
* The vocabulary storage.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\Core\Config\ConfigFactory $config_factory
|
||||
* The config factory.
|
||||
*/
|
||||
public function __construct(VocabularyStorageControllerInterface $vocab_storage, ConfigFactory $config_factory) {
|
||||
$this->vocabStorage = $vocab_storage;
|
||||
public function __construct(EntityManagerInterface $entity_manager, ConfigFactory $config_factory) {
|
||||
parent::__construct($entity_manager);
|
||||
$this->configFactory = $config_factory;
|
||||
}
|
||||
|
||||
|
@ -50,7 +44,7 @@ class TermFormController extends ContentEntityFormController {
|
|||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager')->getStorageController('taxonomy_vocabulary'),
|
||||
$container->get('entity.manager'),
|
||||
$container->get('config.factory')
|
||||
);
|
||||
}
|
||||
|
@ -60,7 +54,8 @@ class TermFormController extends ContentEntityFormController {
|
|||
*/
|
||||
public function form(array $form, array &$form_state) {
|
||||
$term = $this->entity;
|
||||
$vocabulary = $this->vocabStorage->load($term->bundle());
|
||||
$vocab_storage = $this->entityManager->getStorageController('taxonomy_vocabulary');
|
||||
$vocabulary = $vocab_storage->load($term->bundle());
|
||||
|
||||
$parent = array_keys(taxonomy_term_load_parents($term->id()));
|
||||
$form_state['taxonomy']['parent'] = $parent;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\user;
|
||||
|
||||
use Drupal\Core\Entity\ContentEntityFormController;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\Language\LanguageManager;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
@ -27,10 +28,13 @@ abstract class AccountFormController extends ContentEntityFormController {
|
|||
/**
|
||||
* Constructs a new EntityFormController object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\Core\Language\LanguageManager $language_manager
|
||||
* The language manager.
|
||||
*/
|
||||
public function __construct(LanguageManager $language_manager) {
|
||||
public function __construct(EntityManagerInterface $entity_manager, LanguageManager $language_manager) {
|
||||
parent::__construct($entity_manager);
|
||||
$this->languageManager = $language_manager;
|
||||
}
|
||||
|
||||
|
@ -39,6 +43,7 @@ abstract class AccountFormController extends ContentEntityFormController {
|
|||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager'),
|
||||
$container->get('language_manager')
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace Drupal\user\Form;
|
|||
|
||||
use Drupal\Core\Config\ConfigFactory;
|
||||
use Drupal\Core\Entity\ContentEntityConfirmFormBase;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
|
@ -42,8 +43,11 @@ class UserCancelForm extends ContentEntityConfirmFormBase {
|
|||
*
|
||||
* @param \Drupal\Core\Config\ConfigFactory $config_factory
|
||||
* The config factory.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
*/
|
||||
public function __construct(ConfigFactory $config_factory) {
|
||||
public function __construct(EntityManagerInterface $entity_manager, ConfigFactory $config_factory) {
|
||||
parent::__construct($entity_manager);
|
||||
$this->configFactory = $config_factory;
|
||||
}
|
||||
|
||||
|
@ -52,6 +56,7 @@ class UserCancelForm extends ContentEntityConfirmFormBase {
|
|||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager'),
|
||||
$container->get('config.factory')
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue