Drupal 8.0.0 beta 12. More info: https://www.drupal.org/node/2514176
This commit is contained in:
commit
9921556621
13277 changed files with 1459781 additions and 0 deletions
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\config_translation\Controller\ConfigTranslationBlockListBuilder.
|
||||
*/
|
||||
|
||||
namespace Drupal\config_translation\Controller;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Extension\ThemeHandlerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines the config translation list builder for blocks.
|
||||
*/
|
||||
class ConfigTranslationBlockListBuilder extends ConfigTranslationEntityListBuilder {
|
||||
|
||||
/**
|
||||
* An array of theme info keyed by theme name.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $themes = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, ThemeHandlerInterface $theme_handler) {
|
||||
parent::__construct($entity_type, $storage);
|
||||
$this->themes = $theme_handler->listInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
|
||||
return new static(
|
||||
$entity_type,
|
||||
$container->get('entity.manager')->getStorage($entity_type->id()),
|
||||
$container->get('theme_handler')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFilterLabels() {
|
||||
$info = parent::getFilterLabels();
|
||||
|
||||
$info['placeholder'] = $this->t('Enter block, theme or category');
|
||||
$info['description'] = $this->t('Enter a part of the block, theme or category to filter by.');
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildRow(EntityInterface $entity) {
|
||||
$theme = $entity->getTheme();
|
||||
$plugin_definition = $entity->getPlugin()->getPluginDefinition();
|
||||
|
||||
$row['label'] = array(
|
||||
'data' => $this->getLabel($entity),
|
||||
'class' => 'table-filter-text-source',
|
||||
);
|
||||
|
||||
$row['theme'] = array(
|
||||
'data' => SafeMarkup::checkPlain($this->themes[$theme]->info['name']),
|
||||
'class' => 'table-filter-text-source',
|
||||
);
|
||||
|
||||
$row['category'] = array(
|
||||
'data' => SafeMarkup::checkPlain($plugin_definition['category']),
|
||||
'class' => 'table-filter-text-source',
|
||||
);
|
||||
|
||||
$row['operations']['data'] = $this->buildOperations($entity);
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildHeader() {
|
||||
$header['label'] = $this->t('Block');
|
||||
$header['theme'] = $this->t('Theme');
|
||||
$header['category'] = $this->t('Category');
|
||||
$header['operations'] = $this->t('Operations');
|
||||
return $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function sortRows($a, $b) {
|
||||
return $this->sortRowsMultiple($a, $b, array('theme', 'category', 'label'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,216 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\config_translation\Controller\ConfigTranslationController.
|
||||
*/
|
||||
|
||||
namespace Drupal\config_translation\Controller;
|
||||
|
||||
use Drupal\config_translation\ConfigMapperManagerInterface;
|
||||
use Drupal\Core\Access\AccessManagerInterface;
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
|
||||
|
||||
/**
|
||||
* Provides page callbacks for the configuration translation interface.
|
||||
*/
|
||||
class ConfigTranslationController extends ControllerBase {
|
||||
|
||||
/**
|
||||
* The configuration mapper manager.
|
||||
*
|
||||
* @var \Drupal\config_translation\ConfigMapperManagerInterface
|
||||
*/
|
||||
protected $configMapperManager;
|
||||
|
||||
/**
|
||||
* The menu link access service.
|
||||
*
|
||||
* @var \Drupal\Core\Access\AccessManagerInterface
|
||||
*/
|
||||
protected $accessManager;
|
||||
|
||||
/**
|
||||
* The dynamic router service.
|
||||
*
|
||||
* @var \Symfony\Component\Routing\Matcher\RequestMatcherInterface
|
||||
*/
|
||||
protected $router;
|
||||
|
||||
/**
|
||||
* The path processor service.
|
||||
*
|
||||
* @var \Drupal\Core\PathProcessor\InboundPathProcessorInterface
|
||||
*/
|
||||
protected $pathProcessor;
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
protected $account;
|
||||
|
||||
/**
|
||||
* The language manager.
|
||||
*
|
||||
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
|
||||
*/
|
||||
protected $languageManager;
|
||||
|
||||
/**
|
||||
* Constructs a ConfigTranslationController.
|
||||
*
|
||||
* @param \Drupal\config_translation\ConfigMapperManagerInterface $config_mapper_manager
|
||||
* The configuration mapper manager.
|
||||
* @param \Drupal\Core\Access\AccessManagerInterface $access_manager
|
||||
* The menu link access service.
|
||||
* @param \Symfony\Component\Routing\Matcher\RequestMatcherInterface $router
|
||||
* The dynamic router service.
|
||||
* @param \Drupal\Core\PathProcessor\InboundPathProcessorInterface $path_processor
|
||||
* The inbound path processor.
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The current user.
|
||||
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
|
||||
* The language manager.
|
||||
*/
|
||||
public function __construct(ConfigMapperManagerInterface $config_mapper_manager, AccessManagerInterface $access_manager, RequestMatcherInterface $router, InboundPathProcessorInterface $path_processor, AccountInterface $account, LanguageManagerInterface $language_manager) {
|
||||
$this->configMapperManager = $config_mapper_manager;
|
||||
$this->accessManager = $access_manager;
|
||||
$this->router = $router;
|
||||
$this->pathProcessor = $path_processor;
|
||||
$this->account = $account;
|
||||
$this->languageManager = $language_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('plugin.manager.config_translation.mapper'),
|
||||
$container->get('access_manager'),
|
||||
$container->get('router'),
|
||||
$container->get('path_processor_manager'),
|
||||
$container->get('current_user'),
|
||||
$container->get('language_manager')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Language translations overview page for a configuration name.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* Page request object.
|
||||
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
|
||||
* The route match.
|
||||
* @param string $plugin_id
|
||||
* The plugin ID of the mapper.
|
||||
*
|
||||
* @return array
|
||||
* Page render array.
|
||||
*/
|
||||
public function itemPage(Request $request, RouteMatchInterface $route_match, $plugin_id) {
|
||||
/** @var \Drupal\config_translation\ConfigMapperInterface $mapper */
|
||||
$mapper = $this->configMapperManager->createInstance($plugin_id);
|
||||
$mapper->populateFromRequest($request);
|
||||
|
||||
$page = array();
|
||||
$page['#title'] = $this->t('Translations for %label', array('%label' => $mapper->getTitle()));
|
||||
|
||||
$languages = $this->languageManager->getLanguages();
|
||||
if (count($languages) == 1) {
|
||||
drupal_set_message($this->t('In order to translate configuration, the website must have at least two <a href="@url">languages</a>.', array('@url' => $this->url('entity.configurable_language.collection'))), 'warning');
|
||||
}
|
||||
$original_langcode = $mapper->getLangcode();
|
||||
if (!isset($languages[$original_langcode])) {
|
||||
// If the language is not configured on the site, create a dummy language
|
||||
// object for this listing only to ensure the user gets useful info.
|
||||
$language_name = $this->languageManager->getLanguageName($original_langcode);
|
||||
$languages[$original_langcode] = new Language(array('id' => $original_langcode, 'name' => $language_name));
|
||||
}
|
||||
|
||||
// We create a fake request object to pass into
|
||||
// ConfigMapperInterface::populateFromRequest() for the different languages.
|
||||
// Creating a separate request for each language and route is neither easily
|
||||
// possible nor performant.
|
||||
$fake_request = $request->duplicate();
|
||||
|
||||
$page['languages'] = array(
|
||||
'#type' => 'table',
|
||||
'#header' => array($this->t('Language'), $this->t('Operations')),
|
||||
);
|
||||
foreach ($languages as $language) {
|
||||
$langcode = $language->getId();
|
||||
|
||||
// This is needed because
|
||||
// ConfigMapperInterface::getAddRouteParameters(), for example,
|
||||
// needs to return the correct language code for each table row.
|
||||
$fake_request->attributes->set('langcode', $langcode);
|
||||
$mapper->populateFromRequest($fake_request);
|
||||
|
||||
// Prepare the language name and the operations depending on whether this
|
||||
// is the original language or not.
|
||||
if ($langcode == $original_langcode) {
|
||||
$language_name = '<strong>' . $this->t('@language (original)', array('@language' => $language->getName())) . '</strong>';
|
||||
|
||||
// Check access for the path/route for editing, so we can decide to
|
||||
// include a link to edit or not.
|
||||
$edit_access = $this->accessManager->checkNamedRoute($mapper->getBaseRouteName(), $route_match->getRawParameters()->all(), $this->account);
|
||||
|
||||
// Build list of operations.
|
||||
$operations = array();
|
||||
if ($edit_access) {
|
||||
$operations['edit'] = array(
|
||||
'title' => $this->t('Edit'),
|
||||
'url' => Url::fromRoute($mapper->getBaseRouteName(), $mapper->getBaseRouteParameters(), ['query' => ['destination' => $mapper->getOverviewPath()]]),
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$language_name = $language->getName();
|
||||
|
||||
$operations = array();
|
||||
// If no translation exists for this language, link to add one.
|
||||
if (!$mapper->hasTranslation($language)) {
|
||||
$operations['add'] = array(
|
||||
'title' => $this->t('Add'),
|
||||
'url' => Url::fromRoute($mapper->getAddRouteName(), $mapper->getAddRouteParameters()),
|
||||
);
|
||||
}
|
||||
else {
|
||||
// Otherwise, link to edit the existing translation.
|
||||
$operations['edit'] = array(
|
||||
'title' => $this->t('Edit'),
|
||||
'url' => Url::fromRoute($mapper->getEditRouteName(), $mapper->getEditRouteParameters()),
|
||||
);
|
||||
|
||||
$operations['delete'] = array(
|
||||
'title' => $this->t('Delete'),
|
||||
'url' => Url::fromRoute($mapper->getDeleteRouteName(), $mapper->getDeleteRouteParameters()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$page['languages'][$langcode]['language'] = array(
|
||||
'#markup' => $language_name,
|
||||
);
|
||||
|
||||
$page['languages'][$langcode]['operations'] = array(
|
||||
'#type' => 'operations',
|
||||
'#links' => $operations,
|
||||
);
|
||||
}
|
||||
return $page;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\config_translation\Controller\ConfigTranslationEntityListBuilder.
|
||||
*/
|
||||
|
||||
namespace Drupal\config_translation\Controller;
|
||||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
|
||||
|
||||
/**
|
||||
* Defines the configuration translation list builder for entities.
|
||||
*/
|
||||
class ConfigTranslationEntityListBuilder extends ConfigEntityListBuilder implements ConfigTranslationEntityListBuilderInterface {
|
||||
|
||||
/**
|
||||
* Provides user facing strings for the filter element.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getFilterLabels() {
|
||||
return array(
|
||||
'placeholder' => $this->t('Enter label'),
|
||||
'description' => $this->t('Enter a part of the label or description to filter by.'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function render() {
|
||||
$build = parent::render();
|
||||
$filter = $this->getFilterLabels();
|
||||
|
||||
usort($build['table']['#rows'], array($this, 'sortRows'));
|
||||
|
||||
$build['filters'] = array(
|
||||
'#type' => 'container',
|
||||
'#attributes' => array(
|
||||
'class' => array('table-filter', 'js-show'),
|
||||
),
|
||||
'#weight' => -10,
|
||||
);
|
||||
|
||||
$build['filters']['text'] = array(
|
||||
'#type' => 'search',
|
||||
'#title' => $this->t('Search'),
|
||||
'#size' => 30,
|
||||
'#placeholder' => $filter['placeholder'],
|
||||
'#attributes' => array(
|
||||
'class' => array('table-filter-text'),
|
||||
'data-table' => '.config-translation-entity-list',
|
||||
'autocomplete' => 'off',
|
||||
'title' => $filter['description'],
|
||||
),
|
||||
);
|
||||
|
||||
$build['table']['#attributes']['class'][] = 'config-translation-entity-list';
|
||||
$build['table']['#weight'] = 0;
|
||||
$build['#attached']['library'][] = 'system/drupal.system.modules';
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildRow(EntityInterface $entity) {
|
||||
$row['label']['data'] = $this->getLabel($entity);
|
||||
$row['label']['class'][] = 'table-filter-text-source';
|
||||
return $row + parent::buildRow($entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildHeader() {
|
||||
$header['label'] = $this->t('Label');
|
||||
return $header + parent::buildHeader();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefaultOperations(EntityInterface $entity) {
|
||||
$operations = parent::getDefaultOperations($entity);
|
||||
foreach (array_keys($operations) as $operation) {
|
||||
// This is a translation UI for translators. Show the translation
|
||||
// operation only.
|
||||
if (!($operation == 'translate')) {
|
||||
unset($operations[$operation]);
|
||||
}
|
||||
}
|
||||
return $operations;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function sortRows($a, $b) {
|
||||
return $this->sortRowsMultiple($a, $b, array('label'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array by multiple criteria.
|
||||
*
|
||||
* @param array $a
|
||||
* First item for comparison.
|
||||
* @param array $b
|
||||
* Second item for comparison.
|
||||
* @param array $keys
|
||||
* The array keys to sort on.
|
||||
*
|
||||
* @return int
|
||||
* The comparison result for uasort().
|
||||
*/
|
||||
protected function sortRowsMultiple($a, $b, $keys) {
|
||||
$key = array_shift($keys);
|
||||
$a_value = (is_array($a) && isset($a[$key]['data'])) ? $a[$key]['data'] : '';
|
||||
$b_value = (is_array($b) && isset($b[$key]['data'])) ? $b[$key]['data'] : '';
|
||||
|
||||
if ($a_value == $b_value && !empty($keys)) {
|
||||
return $this->sortRowsMultiple($a, $b, $keys);
|
||||
}
|
||||
|
||||
return strnatcasecmp($a_value, $b_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMapperDefinition($mapper_definition) {
|
||||
// @todo Why is this method called on all config list controllers?
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\config_translation\Controller\ConfigTranslationEntityListBuilderInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\config_translation\Controller;
|
||||
|
||||
use Drupal\Core\Entity\EntityListBuilderInterface;
|
||||
|
||||
/**
|
||||
* Defines an interface for configuration translation entity list builders.
|
||||
*/
|
||||
interface ConfigTranslationEntityListBuilderInterface extends EntityListBuilderInterface {
|
||||
|
||||
/**
|
||||
* Sorts an array by value.
|
||||
*
|
||||
* @param array $a
|
||||
* First item for comparison.
|
||||
* @param array $b
|
||||
* Second item for comparison.
|
||||
*
|
||||
* @return int
|
||||
* The comparison result for uasort().
|
||||
*/
|
||||
public function sortRows($a, $b);
|
||||
|
||||
/**
|
||||
* Sets the config translation mapper definition.
|
||||
*
|
||||
* @param mixed $mapper_definition
|
||||
* The plugin definition of the config translation mapper.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setMapperDefinition($mapper_definition);
|
||||
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\config_translation\Controller\ConfigTranslationFieldListBuilder.
|
||||
*/
|
||||
|
||||
namespace Drupal\config_translation\Controller;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines the config translation list builder for field entities.
|
||||
*/
|
||||
class ConfigTranslationFieldListBuilder extends ConfigTranslationEntityListBuilder {
|
||||
|
||||
/**
|
||||
* The name of the entity type the fields are attached to.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $baseEntityType = '';
|
||||
|
||||
/**
|
||||
* An array containing the base entity type's definition.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $baseEntityInfo = array();
|
||||
|
||||
/**
|
||||
* The bundle info for the base entity type.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $baseEntityBundles = array();
|
||||
|
||||
/**
|
||||
* The entity manager.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
|
||||
$entity_manager = $container->get('entity.manager');
|
||||
return new static(
|
||||
$entity_type,
|
||||
$entity_manager->getStorage($entity_type->id()),
|
||||
$entity_manager
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new ConfigTranslationFieldListBuilder object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
|
||||
* The entity type definition.
|
||||
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
|
||||
* The entity storage class.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
*/
|
||||
public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, EntityManagerInterface $entity_manager) {
|
||||
parent::__construct($entity_type, $storage);
|
||||
$this->entityManager = $entity_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMapperDefinition($mapper_definition) {
|
||||
$this->baseEntityType = $mapper_definition['base_entity_type'];
|
||||
$this->baseEntityInfo = $this->entityManager->getDefinition($this->baseEntityType);
|
||||
$this->baseEntityBundles = $this->entityManager->getBundleInfo($this->baseEntityType);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load() {
|
||||
// It is not possible to use the standard load method, because this needs
|
||||
// all field entities only for the given baseEntityType.
|
||||
$ids = \Drupal::entityQuery('field_config')
|
||||
->condition('id', $this->baseEntityType . '.', 'STARTS_WITH')
|
||||
->execute();
|
||||
return $this->storage->loadMultiple($ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFilterLabels() {
|
||||
$info = parent::getFilterLabels();
|
||||
$bundle = $this->baseEntityInfo->getBundleLabel() ?: $this->t('Bundle');
|
||||
$bundle = Unicode::strtolower($bundle);
|
||||
|
||||
$info['placeholder'] = $this->t('Enter field or @bundle', array('@bundle' => $bundle));
|
||||
$info['description'] = $this->t('Enter a part of the field or @bundle to filter by.', array('@bundle' => $bundle));
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildRow(EntityInterface $entity) {
|
||||
$row['label'] = array(
|
||||
'data' => $this->getLabel($entity),
|
||||
'class' => 'table-filter-text-source',
|
||||
);
|
||||
|
||||
if ($this->displayBundle()) {
|
||||
$bundle = $entity->get('bundle');
|
||||
$row['bundle'] = array(
|
||||
'data' => SafeMarkup::checkPlain($this->baseEntityBundles[$bundle]['label']),
|
||||
'class' => 'table-filter-text-source',
|
||||
);
|
||||
}
|
||||
|
||||
return $row + parent::buildRow($entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildHeader() {
|
||||
$header['label'] = $this->t('Field');
|
||||
if ($this->displayBundle()) {
|
||||
$header['bundle'] = $this->baseEntityInfo->getBundleLabel() ?: $this->t('Bundle');
|
||||
}
|
||||
return $header + parent::buildHeader();
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls the visibility of the bundle column on field list pages.
|
||||
*
|
||||
* @return bool
|
||||
* Whenever the bundle is displayed or not.
|
||||
*/
|
||||
public function displayBundle() {
|
||||
// The bundle key is explicitly defined in the entity definition.
|
||||
if ($this->baseEntityInfo->getKey('bundle')) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// There is more than one bundle defined.
|
||||
if (count($this->baseEntityBundles) > 1) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// The defined bundle ones not match the entity type name.
|
||||
if (!empty($this->baseEntityBundles) && !isset($this->baseEntityBundles[$this->baseEntityType])) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function sortRows($a, $b) {
|
||||
return $this->sortRowsMultiple($a, $b, array('bundle', 'label'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\config_translation\Controller\ConfigTranslationListController.
|
||||
*/
|
||||
|
||||
namespace Drupal\config_translation\Controller;
|
||||
|
||||
use Drupal\config_translation\ConfigMapperManagerInterface;
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* Defines the configuration translation list controller.
|
||||
*/
|
||||
class ConfigTranslationListController extends ControllerBase {
|
||||
|
||||
/**
|
||||
* The mapper manager.
|
||||
*
|
||||
* @var \Drupal\config_translation\ConfigMapperManagerInterface
|
||||
*/
|
||||
protected $mapperManager;
|
||||
|
||||
/**
|
||||
* Constructs a new ConfigTranslationListController object.
|
||||
*
|
||||
* @param \Drupal\config_translation\ConfigMapperManagerInterface $mapper_manager
|
||||
* The config mapper manager.
|
||||
*/
|
||||
public function __construct(ConfigMapperManagerInterface $mapper_manager) {
|
||||
$this->mapperManager = $mapper_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('plugin.manager.config_translation.mapper')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the listing page for any entity type.
|
||||
*
|
||||
* @param string $mapper_id
|
||||
* The name of the mapper.
|
||||
*
|
||||
* @return array
|
||||
* A render array as expected by drupal_render().
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
|
||||
* Throws an exception if a mapper plugin could not be instantiated from the
|
||||
* mapper definition in the constructor.
|
||||
*/
|
||||
public function listing($mapper_id) {
|
||||
$mapper_definition = $this->mapperManager->getDefinition($mapper_id);
|
||||
$mapper = $this->mapperManager->createInstance($mapper_id, $mapper_definition);
|
||||
if (!$mapper) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
$entity_type = $mapper->getType();
|
||||
// If the mapper, for example the mapper for fields, has a custom list
|
||||
// controller defined, use it. Other mappers, for examples the ones for
|
||||
// node_type and block, fallback to the generic configuration translation
|
||||
// list controller.
|
||||
$build = $this->entityManager()
|
||||
->getHandler($entity_type, 'config_translation_list')
|
||||
->setMapperDefinition($mapper_definition)
|
||||
->render();
|
||||
$build['#title'] = $mapper->getTypeLabel();
|
||||
return $build;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\config_translation\Controller\ConfigTranslationMapperList.
|
||||
*/
|
||||
|
||||
namespace Drupal\config_translation\Controller;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\config_translation\ConfigMapperInterface;
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines the configuration translation mapper list.
|
||||
*
|
||||
* Groups all defined configuration mapper instances by weight.
|
||||
*/
|
||||
class ConfigTranslationMapperList extends ControllerBase {
|
||||
|
||||
/**
|
||||
* A array of configuration mapper instances.
|
||||
*
|
||||
* @var \Drupal\config_translation\ConfigMapperInterface[]
|
||||
*/
|
||||
protected $mappers;
|
||||
|
||||
/**
|
||||
* Constructs a new ConfigTranslationMapperList object.
|
||||
*
|
||||
* @param \Drupal\config_translation\ConfigMapperInterface[] $mappers
|
||||
* The configuration mapper manager.
|
||||
*/
|
||||
public function __construct(array $mappers) {
|
||||
$this->mappers = $mappers;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('plugin.manager.config_translation.mapper')->getMappers()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the mappers as a renderable array for table.html.twig.
|
||||
*
|
||||
* @return array
|
||||
* Renderable array with config translation mappers.
|
||||
*/
|
||||
public function render() {
|
||||
$build = array(
|
||||
'#type' => 'table',
|
||||
'#header' => $this->buildHeader(),
|
||||
'#rows' => array(),
|
||||
);
|
||||
|
||||
$mappers = array();
|
||||
|
||||
foreach ($this->mappers as $mapper) {
|
||||
if ($row = $this->buildRow($mapper)) {
|
||||
$mappers[$mapper->getWeight()][] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
// Group by mapper weight and sort by label.
|
||||
ksort($mappers);
|
||||
foreach ($mappers as $weight => $mapper) {
|
||||
usort($mapper, function ($a, $b) {
|
||||
$a_title = (isset($a['label'])) ? $a['label'] : '';
|
||||
$b_title = (isset($b['label'])) ? $b['label'] : '';
|
||||
return strnatcasecmp($a_title, $b_title);
|
||||
});
|
||||
$mappers[$weight] = $mapper;
|
||||
}
|
||||
|
||||
foreach ($mappers as $mapper) {
|
||||
$build['#rows'] = array_merge($build['#rows'], $mapper);
|
||||
}
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a row for a mapper in the mapper listing.
|
||||
*
|
||||
* @param \Drupal\config_translation\ConfigMapperInterface $mapper
|
||||
* The mapper.
|
||||
*
|
||||
* @return array
|
||||
* A render array structure of fields for this mapper.
|
||||
*/
|
||||
public function buildRow(ConfigMapperInterface $mapper) {
|
||||
$row['label'] = SafeMarkup::checkPlain($mapper->getTypeLabel());
|
||||
$row['operations']['data'] = $this->buildOperations($mapper);
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the header row for the mapper listing.
|
||||
*
|
||||
* @return array
|
||||
* A render array structure of header strings.
|
||||
*/
|
||||
public function buildHeader() {
|
||||
$row['Label'] = $this->t('Label');
|
||||
$row['operations'] = $this->t('Operations');
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a renderable list of operation links for the entity.
|
||||
*
|
||||
* @param \Drupal\config_translation\ConfigMapperInterface $mapper
|
||||
* The mapper.
|
||||
*
|
||||
* @return array
|
||||
* A renderable array of operation links.
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityList::buildOperations()
|
||||
*/
|
||||
protected function buildOperations(ConfigMapperInterface $mapper) {
|
||||
// Retrieve and sort operations.
|
||||
$operations = $mapper->getOperations();
|
||||
uasort($operations, 'Drupal\Component\Utility\SortArray::sortByWeightElement');
|
||||
$build = array(
|
||||
'#type' => 'operations',
|
||||
'#links' => $operations,
|
||||
);
|
||||
return $build;
|
||||
}
|
||||
|
||||
}
|
Reference in a new issue