Update Composer, update everything
This commit is contained in:
parent
ea3e94409f
commit
dda5c284b6
19527 changed files with 1135420 additions and 351004 deletions
|
|
@ -5,7 +5,7 @@ namespace Drupal\user\Plugin\Action;
|
|||
use Drupal\Core\Action\ActionBase;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\user\PrivateTempStoreFactory;
|
||||
use Drupal\Core\TempStore\PrivateTempStoreFactory;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
|
|
@ -23,7 +23,7 @@ class CancelUser extends ActionBase implements ContainerFactoryPluginInterface {
|
|||
/**
|
||||
* The tempstore factory.
|
||||
*
|
||||
* @var \Drupal\user\PrivateTempStoreFactory
|
||||
* @var \Drupal\Core\TempStore\PrivateTempStoreFactory
|
||||
*/
|
||||
protected $tempStoreFactory;
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ class CancelUser extends ActionBase implements ContainerFactoryPluginInterface {
|
|||
protected $currentUser;
|
||||
|
||||
/**
|
||||
* Constructs a DeleteNode object.
|
||||
* Constructs a CancelUser object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
|
|
@ -43,9 +43,9 @@ class CancelUser extends ActionBase implements ContainerFactoryPluginInterface {
|
|||
* The plugin ID for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
|
||||
* @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
|
||||
* The tempstore factory.
|
||||
* @param AccountInterface $current_user
|
||||
* @param \Drupal\Core\Session\AccountInterface $current_user
|
||||
* Current user.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, PrivateTempStoreFactory $temp_store_factory, AccountInterface $current_user) {
|
||||
|
|
@ -63,7 +63,7 @@ class CancelUser extends ActionBase implements ContainerFactoryPluginInterface {
|
|||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('user.private_tempstore'),
|
||||
$container->get('tempstore.private'),
|
||||
$container->get('current_user')
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ use Drupal\Core\Access\AccessResult;
|
|||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Routing\RedirectDestinationTrait;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\Routing\UrlGeneratorTrait;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Block\BlockBase;
|
||||
|
|
@ -23,7 +22,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
*/
|
||||
class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
use UrlGeneratorTrait;
|
||||
use RedirectDestinationTrait;
|
||||
|
||||
/**
|
||||
|
|
@ -66,7 +64,6 @@ class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterfac
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
@ -94,7 +91,24 @@ class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterfac
|
|||
unset($form['pass']['#attributes']['aria-describedby']);
|
||||
$form['name']['#size'] = 15;
|
||||
$form['pass']['#size'] = 15;
|
||||
$form['#action'] = $this->url('<current>', [], ['query' => $this->getDestinationArray(), 'external' => FALSE]);
|
||||
|
||||
// Instead of setting an actual action URL, we set the placeholder, which
|
||||
// will be replaced at the very last moment. This ensures forms with
|
||||
// dynamically generated action URLs don't have poor cacheability.
|
||||
// Use the proper API to generate the placeholder, when we have one. See
|
||||
// https://www.drupal.org/node/2562341. The placeholder uses a fixed string
|
||||
// that is
|
||||
// Crypt::hashBase64('\Drupal\user\Plugin\Block\UserLoginBlock::build');
|
||||
// This is based on the implementation in
|
||||
// \Drupal\Core\Form\FormBuilder::prepareForm(), but the user login block
|
||||
// requires different behavior for the destination query argument.
|
||||
$placeholder = 'form_action_p_4r8ITd22yaUvXM6SzwrSe9rnQWe48hz9k1Sxto3pBvE';
|
||||
|
||||
$form['#attached']['placeholders'][$placeholder] = [
|
||||
'#lazy_builder' => ['\Drupal\user\Plugin\Block\UserLoginBlock::renderPlaceholderFormAction', []],
|
||||
];
|
||||
$form['#action'] = $placeholder;
|
||||
|
||||
// Build action links.
|
||||
$items = [];
|
||||
if (\Drupal::config('user.settings')->get('register') != USER_REGISTER_ADMINISTRATORS_ONLY) {
|
||||
|
|
@ -128,4 +142,20 @@ class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterfac
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* #lazy_builder callback; renders a form action URL including destination.
|
||||
*
|
||||
* @return array
|
||||
* A renderable array representing the form action.
|
||||
*
|
||||
* @see \Drupal\Core\Form\FormBuilder::renderPlaceholderFormAction()
|
||||
*/
|
||||
public static function renderPlaceholderFormAction() {
|
||||
return [
|
||||
'#type' => 'markup',
|
||||
'#markup' => Url::fromRoute('<current>', [], ['query' => \Drupal::destination()->getAsArray(), 'external' => FALSE])->toString(),
|
||||
'#cache' => ['contexts' => ['url.path', 'url.query_args']],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace Drupal\user\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
|
||||
|
|
@ -82,21 +83,26 @@ class UserSelection extends DefaultSelection {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$selection_handler_settings = $this->configuration['handler_settings'];
|
||||
|
||||
// Merge in default values.
|
||||
$selection_handler_settings += [
|
||||
public function defaultConfiguration() {
|
||||
return [
|
||||
'filter' => [
|
||||
'type' => '_none',
|
||||
'role' => NULL,
|
||||
],
|
||||
'include_anonymous' => TRUE,
|
||||
];
|
||||
] + parent::defaultConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$configuration = $this->getConfiguration();
|
||||
|
||||
$form['include_anonymous'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Include the anonymous user.'),
|
||||
'#default_value' => $selection_handler_settings['include_anonymous'],
|
||||
'#default_value' => $configuration['include_anonymous'],
|
||||
];
|
||||
|
||||
// Add user specific filter options.
|
||||
|
|
@ -109,7 +115,7 @@ class UserSelection extends DefaultSelection {
|
|||
],
|
||||
'#ajax' => TRUE,
|
||||
'#limit_validation_errors' => [],
|
||||
'#default_value' => $selection_handler_settings['filter']['type'],
|
||||
'#default_value' => $configuration['filter']['type'],
|
||||
];
|
||||
|
||||
$form['filter']['settings'] = [
|
||||
|
|
@ -118,18 +124,13 @@ class UserSelection extends DefaultSelection {
|
|||
'#process' => [['\Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem', 'formProcessMergeParent']],
|
||||
];
|
||||
|
||||
if ($selection_handler_settings['filter']['type'] == 'role') {
|
||||
// Merge in default values.
|
||||
$selection_handler_settings['filter'] += [
|
||||
'role' => NULL,
|
||||
];
|
||||
|
||||
if ($configuration['filter']['type'] == 'role') {
|
||||
$form['filter']['settings']['role'] = [
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => $this->t('Restrict to the selected roles'),
|
||||
'#required' => TRUE,
|
||||
'#options' => array_diff_key(user_role_names(TRUE), [RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID]),
|
||||
'#default_value' => $selection_handler_settings['filter']['role'],
|
||||
'#default_value' => $configuration['filter']['role'],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -143,11 +144,12 @@ class UserSelection extends DefaultSelection {
|
|||
*/
|
||||
protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
|
||||
$query = parent::buildEntityQuery($match, $match_operator);
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
|
||||
$configuration = $this->getConfiguration();
|
||||
|
||||
// Filter out the Anonymous user if the selection handler is configured to
|
||||
// exclude it.
|
||||
if (isset($handler_settings['include_anonymous']) && !$handler_settings['include_anonymous']) {
|
||||
if (!$configuration['include_anonymous']) {
|
||||
$query->condition('uid', 0, '<>');
|
||||
}
|
||||
|
||||
|
|
@ -157,8 +159,8 @@ class UserSelection extends DefaultSelection {
|
|||
}
|
||||
|
||||
// Filter by role.
|
||||
if (!empty($handler_settings['filter']['role'])) {
|
||||
$query->condition('roles', $handler_settings['filter']['role'], 'IN');
|
||||
if (!empty($configuration['filter']['role'])) {
|
||||
$query->condition('roles', $configuration['filter']['role'], 'IN');
|
||||
}
|
||||
|
||||
// Adding the permission check is sadly insufficient for users: core
|
||||
|
|
@ -190,10 +192,10 @@ class UserSelection extends DefaultSelection {
|
|||
public function validateReferenceableNewEntities(array $entities) {
|
||||
$entities = parent::validateReferenceableNewEntities($entities);
|
||||
// Mirror the conditions checked in buildEntityQuery().
|
||||
if (!empty($this->configuration['handler_settings']['filter']['role'])) {
|
||||
$entities = array_filter($entities, function ($user) {
|
||||
if ($role = $this->getConfiguration()['filter']['role']) {
|
||||
$entities = array_filter($entities, function ($user) use ($role) {
|
||||
/** @var \Drupal\user\UserInterface $user */
|
||||
return !empty(array_intersect($user->getRoles(), $this->configuration['handler_settings']['filter']['role']));
|
||||
return !empty(array_intersect($user->getRoles(), $role));
|
||||
});
|
||||
}
|
||||
if (!$this->currentUser->hasPermission('administer users')) {
|
||||
|
|
@ -209,9 +211,10 @@ class UserSelection extends DefaultSelection {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function entityQueryAlter(SelectInterface $query) {
|
||||
parent::entityQueryAlter($query);
|
||||
|
||||
// Bail out early if we do not need to match the Anonymous user.
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
if (isset($handler_settings['include_anonymous']) && !$handler_settings['include_anonymous']) {
|
||||
if (!$this->getConfiguration()['include_anonymous']) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -228,18 +231,18 @@ class UserSelection extends DefaultSelection {
|
|||
// Re-add the condition and a condition on uid = 0 so that we end up
|
||||
// with a query in the form:
|
||||
// WHERE (name LIKE :name) OR (:anonymous_name LIKE :name AND uid = 0)
|
||||
$or = db_or();
|
||||
$or = new Condition('OR');
|
||||
$or->condition($condition['field'], $condition['value'], $condition['operator']);
|
||||
// Sadly, the Database layer doesn't allow us to build a condition
|
||||
// in the form ':placeholder = :placeholder2', because the 'field'
|
||||
// part of a condition is always escaped.
|
||||
// As a (cheap) workaround, we separately build a condition with no
|
||||
// field, and concatenate the field and the condition separately.
|
||||
$value_part = db_and();
|
||||
$value_part = new Condition('AND');
|
||||
$value_part->condition('anonymous_name', $condition['value'], $condition['operator']);
|
||||
$value_part->compile($this->connection, $query);
|
||||
$or->condition(db_and()
|
||||
->where(str_replace('anonymous_name', ':anonymous_name', (string) $value_part), $value_part->arguments() + [':anonymous_name' => \Drupal::config('user.settings')->get('anonymous')])
|
||||
$or->condition((new Condition('AND'))
|
||||
->where(str_replace($query->escapeField('anonymous_name'), ':anonymous_name', (string) $value_part), $value_part->arguments() + [':anonymous_name' => \Drupal::config('user.settings')->get('anonymous')])
|
||||
->condition('base_table.uid', 0)
|
||||
);
|
||||
$query->condition($or);
|
||||
|
|
|
|||
|
|
@ -30,10 +30,9 @@ class LanguageNegotiationUser extends LanguageNegotiationMethodBase {
|
|||
|
||||
// User preference (only for authenticated users).
|
||||
if ($this->languageManager && $this->currentUser->isAuthenticated()) {
|
||||
$preferred_langcode = $this->currentUser->getPreferredLangcode();
|
||||
$default_langcode = $this->languageManager->getDefaultLanguage()->getId();
|
||||
$preferred_langcode = $this->currentUser->getPreferredLangcode(FALSE);
|
||||
$languages = $this->languageManager->getLanguages();
|
||||
if (!empty($preferred_langcode) && $preferred_langcode != $default_langcode && isset($languages[$preferred_langcode])) {
|
||||
if (!empty($preferred_langcode) && isset($languages[$preferred_langcode])) {
|
||||
$langcode = $preferred_langcode;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,10 +127,14 @@ class LanguageNegotiationUserAdmin extends LanguageNegotiationMethodBase impleme
|
|||
$route_match = $this->stackedRouteMatch->getRouteMatchFromRequest($request);
|
||||
if ($route_match && !$route_object = $route_match->getRouteObject()) {
|
||||
try {
|
||||
// Some inbound path processors make changes to the request. Make a
|
||||
// copy as we're not actually routing the request so we do not want to
|
||||
// make changes.
|
||||
$cloned_request = clone $request;
|
||||
// Process the path as an inbound path. This will remove any language
|
||||
// prefixes and other path components that inbound processing would
|
||||
// clear out, so we can attempt to load the route clearly.
|
||||
$path = $this->pathProcessorManager->processInbound(urldecode(rtrim($request->getPathInfo(), '/')), $request);
|
||||
$path = $this->pathProcessorManager->processInbound(urldecode(rtrim($cloned_request->getPathInfo(), '/')), $cloned_request);
|
||||
$attributes = $this->router->match($path);
|
||||
}
|
||||
catch (ResourceNotFoundException $e) {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class UserSearch extends SearchPluginBase implements AccessibleInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
static public function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$container->get('database'),
|
||||
$container->get('entity.manager'),
|
||||
|
|
@ -67,11 +67,11 @@ class UserSearch extends SearchPluginBase implements AccessibleInterface {
|
|||
/**
|
||||
* Creates a UserSearch object.
|
||||
*
|
||||
* @param Connection $database
|
||||
* @param \Drupal\Core\Database\Connection $database
|
||||
* The database connection.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param ModuleHandlerInterface $module_handler
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler.
|
||||
* @param \Drupal\Core\Session\AccountInterface $current_user
|
||||
* The current user.
|
||||
|
|
@ -162,13 +162,15 @@ class UserSearch extends SearchPluginBase implements AccessibleInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHelp() {
|
||||
$help = ['list' => [
|
||||
'#theme' => 'item_list',
|
||||
'#items' => [
|
||||
$this->t('User search looks for user names and partial user names. Example: mar would match usernames mar, delmar, and maryjane.'),
|
||||
$this->t('You can use * as a wildcard within your keyword. Example: m*r would match user names mar, delmar, and elementary.'),
|
||||
$help = [
|
||||
'list' => [
|
||||
'#theme' => 'item_list',
|
||||
'#items' => [
|
||||
$this->t('User search looks for user names and partial user names. Example: mar would match usernames mar, delmar, and maryjane.'),
|
||||
$this->t('You can use * as a wildcard within your keyword. Example: m*r would match user names mar, delmar, and elementary.'),
|
||||
],
|
||||
],
|
||||
]];
|
||||
];
|
||||
|
||||
return $help;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Drupal\user\Plugin\Validation\Constraint;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
|
||||
|
|
@ -53,7 +52,7 @@ class UserNameConstraintValidator extends ConstraintValidator {
|
|||
) {
|
||||
$this->context->addViolation($constraint->illegalMessage);
|
||||
}
|
||||
if (Unicode::strlen($name) > USERNAME_MAX_LENGTH) {
|
||||
if (mb_strlen($name) > USERNAME_MAX_LENGTH) {
|
||||
$this->context->addViolation($constraint->tooLongMessage, ['%name' => $name, '%max' => USERNAME_MAX_LENGTH]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
namespace Drupal\user\Plugin\migrate;
|
||||
|
||||
use Drupal\migrate\Exception\RequirementsException;
|
||||
use Drupal\migrate\MigrateExecutable;
|
||||
use Drupal\migrate\MigrateSkipRowException;
|
||||
use Drupal\migrate\Plugin\Migration;
|
||||
|
||||
/**
|
||||
|
|
@ -28,13 +30,31 @@ class ProfileValues extends Migration {
|
|||
'ignore_map' => TRUE,
|
||||
] + $this->source;
|
||||
$definition['destination']['plugin'] = 'null';
|
||||
$definition['idMap']['plugin'] = 'null';
|
||||
try {
|
||||
$profile_field_migration = $this->migrationPluginManager->createStubMigration($definition);
|
||||
$migrate_executable = new MigrateExecutable($profile_field_migration);
|
||||
$source_plugin = $profile_field_migration->getSourcePlugin();
|
||||
$source_plugin->checkRequirements();
|
||||
foreach ($source_plugin as $row) {
|
||||
$name = $row->getSourceProperty('name');
|
||||
$this->process[$name] = $name;
|
||||
$fid = $row->getSourceProperty('fid');
|
||||
// The user profile field name can be greater than 32 characters. Use
|
||||
// the migrated profile field name in the process pipeline.
|
||||
$configuration =
|
||||
[
|
||||
'migration' => 'user_profile_field',
|
||||
'source_ids' => $fid,
|
||||
];
|
||||
$plugin = $this->processPluginManager->createInstance('migration_lookup', $configuration, $profile_field_migration);
|
||||
$new_value = $plugin->transform($fid, $migrate_executable, $row, 'tmp');
|
||||
if (isset($new_value[1])) {
|
||||
// Set the destination to the migrated profile field name.
|
||||
$this->process[$new_value[1]] = $name;
|
||||
}
|
||||
else {
|
||||
throw new MigrateSkipRowException("Can't migrate source field $name.");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (RequirementsException $e) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ class User extends FieldMigration {
|
|||
'ignore_map' => TRUE,
|
||||
] + $this->source;
|
||||
$definition['destination']['plugin'] = 'null';
|
||||
$definition['idMap']['plugin'] = 'null';
|
||||
if (\Drupal::moduleHandler()->moduleExists('field')) {
|
||||
$definition['source']['plugin'] = 'd7_field_instance';
|
||||
$field_migration = $this->migrationPluginManager->createStubMigration($definition);
|
||||
|
|
@ -36,7 +37,7 @@ class User extends FieldMigration {
|
|||
}
|
||||
$info = $row->getSource();
|
||||
$this->fieldPluginCache[$field_type]
|
||||
->processFieldValues($this, $field_name, $info);
|
||||
->defineValueProcessPipeline($this, $field_name, $info);
|
||||
}
|
||||
else {
|
||||
if ($this->cckPluginManager->hasDefinition($field_type)) {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Drupal\user\Plugin\migrate\destination;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Entity\ContentEntityInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
|
|
@ -15,6 +14,52 @@ use Drupal\migrate\Row;
|
|||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a destination plugin for migrating user entities.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* The example below migrates users and preserves original passwords from a
|
||||
* source that has passwords as MD5 hashes without salt. The passwords will be
|
||||
* salted and re-hashed before they are saved to the destination Drupal
|
||||
* database. The MD5 hash used in the example is a hash of 'password'.
|
||||
*
|
||||
* The example uses the EmbeddedDataSource source plugin for the sake of
|
||||
* simplicity. The mapping between old user_ids and new Drupal uids is saved in
|
||||
* the migration map table.
|
||||
* @code
|
||||
* id: custom_user_migration
|
||||
* label: Custom user migration
|
||||
* source:
|
||||
* plugin: embedded_data
|
||||
* data_rows:
|
||||
* -
|
||||
* user_id: 1
|
||||
* name: johnsmith
|
||||
* mail: johnsmith@example.com
|
||||
* hash: '5f4dcc3b5aa765d61d8327deb882cf99'
|
||||
* ids:
|
||||
* user_id:
|
||||
* type: integer
|
||||
* process:
|
||||
* name: name
|
||||
* mail: mail
|
||||
* pass: hash
|
||||
* status:
|
||||
* plugin: default_value
|
||||
* default_value: 1
|
||||
* destination:
|
||||
* plugin: entity:user
|
||||
* md5_passwords: true
|
||||
* @endcode
|
||||
*
|
||||
* For configuration options inherited from the parent class, refer to
|
||||
* \Drupal\migrate\Plugin\migrate\destination\EntityContentBase.
|
||||
*
|
||||
* The example above is about migrating an MD5 password hash. For more examples
|
||||
* on different password hash types and a list of other user properties, refer
|
||||
* to the handbook documentation:
|
||||
* @see https://www.drupal.org/docs/8/api/migrate-api/migrate-destination-plugins-examples/migrating-users
|
||||
*
|
||||
* @MigrateDestination(
|
||||
* id = "entity:user"
|
||||
* )
|
||||
|
|
@ -39,7 +84,7 @@ class EntityUser extends EntityContentBase {
|
|||
* The plugin implementation definition.
|
||||
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
|
||||
* The migration.
|
||||
* @param EntityStorageInterface $storage
|
||||
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
|
||||
* The storage for this entity type.
|
||||
* @param array $bundles
|
||||
* The list of bundles this entity type has.
|
||||
|
|
@ -122,9 +167,23 @@ class EntityUser extends EntityContentBase {
|
|||
if (is_array($name)) {
|
||||
$name = reset($name);
|
||||
}
|
||||
if (Unicode::strlen($name) > USERNAME_MAX_LENGTH) {
|
||||
$row->setDestinationProperty('name', Unicode::substr($name, 0, USERNAME_MAX_LENGTH));
|
||||
if (mb_strlen($name) > USERNAME_MAX_LENGTH) {
|
||||
$row->setDestinationProperty('name', mb_substr($name, 0, USERNAME_MAX_LENGTH));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHighestId() {
|
||||
$highest_id = parent::getHighestId();
|
||||
|
||||
// Every Drupal site must have a user with UID of 1 and it's normal for
|
||||
// migrations to overwrite this user.
|
||||
if ($highest_id === 1) {
|
||||
return 0;
|
||||
}
|
||||
return $highest_id;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class UserLangcode extends ProcessPluginBase implements ContainerFactoryPluginIn
|
|||
* @param string $plugin_id
|
||||
* The plugin ID.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin definiiton.
|
||||
* The plugin definition.
|
||||
* @param \Drupal\Core\Language\LanguageManager $language_manager
|
||||
* The language manager service.
|
||||
*/
|
||||
|
|
@ -74,7 +74,7 @@ class UserLangcode extends ProcessPluginBase implements ContainerFactoryPluginIn
|
|||
return 'en';
|
||||
}
|
||||
}
|
||||
// If the user's language does not exists, use the default language.
|
||||
// If the user's language does not exist, use the default language.
|
||||
elseif ($this->languageManager->getLanguage($value) === NULL) {
|
||||
return $this->languageManager->getDefaultLanguage()->getId();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ class UserUpdate7002 extends ProcessPluginBase implements ContainerFactoryPlugin
|
|||
$container->get('config.factory')->get('system.date')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use Drupal\migrate\Row;
|
|||
*
|
||||
* @MigrateSource(
|
||||
* id = "profile_field",
|
||||
* source_provider = "profile"
|
||||
* source_module = "profile"
|
||||
* )
|
||||
*/
|
||||
class ProfileField extends DrupalSqlBase {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ use Drupal\migrate\Plugin\migrate\source\DummyQueryTrait;
|
|||
* @todo Support default picture?
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "user_picture_instance"
|
||||
* id = "user_picture_instance",
|
||||
* source_module = "user"
|
||||
* )
|
||||
*/
|
||||
class UserPictureInstance extends DrupalSqlBase {
|
||||
|
|
@ -28,7 +29,8 @@ class UserPictureInstance extends DrupalSqlBase {
|
|||
'file_directory' => $this->variableGet('user_picture_path', 'pictures'),
|
||||
'max_filesize' => $this->variableGet('user_picture_file_size', '30') . 'KB',
|
||||
'max_resolution' => $this->variableGet('user_picture_dimensions', '85x85'),
|
||||
]]);
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
|||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_profile_field_values",
|
||||
* source_provider = "profile"
|
||||
* source_module = "profile"
|
||||
* )
|
||||
*/
|
||||
class ProfileFieldValues extends DrupalSqlBase {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
|||
* Drupal 6 role source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_user_role"
|
||||
* id = "d6_user_role",
|
||||
* source_module = "user"
|
||||
* )
|
||||
*/
|
||||
class Role extends DrupalSqlBase {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
|||
* Drupal 6 user source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_user"
|
||||
* id = "d6_user",
|
||||
* source_module = "user"
|
||||
* )
|
||||
*/
|
||||
class User extends DrupalSqlBase {
|
||||
|
|
@ -32,14 +33,6 @@ class User extends DrupalSqlBase {
|
|||
// Add roles field.
|
||||
$fields['roles'] = $this->t('Roles');
|
||||
|
||||
// Profile fields.
|
||||
if ($this->moduleExists('profile')) {
|
||||
$fields += $this->select('profile_fields', 'pf')
|
||||
->fields('pf', ['name', 'title'])
|
||||
->execute()
|
||||
->fetchAllKeyed();
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
|||
* @todo Support default picture?
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_user_picture"
|
||||
* id = "d6_user_picture",
|
||||
* source_module = "user"
|
||||
* )
|
||||
*/
|
||||
class UserPicture extends DrupalSqlBase {
|
||||
|
|
@ -36,6 +37,7 @@ class UserPicture extends DrupalSqlBase {
|
|||
'picture' => "Path to the user's uploaded picture.",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ use Drupal\migrate\Row;
|
|||
* Drupal 6 user picture source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_user_picture_file"
|
||||
* id = "d6_user_picture_file",
|
||||
* source_module = "user"
|
||||
* )
|
||||
*/
|
||||
class UserPictureFile extends DrupalSqlBase {
|
||||
|
|
@ -67,6 +68,7 @@ class UserPictureFile extends DrupalSqlBase {
|
|||
'filename' => 'The picture filename.',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
|||
* Drupal 7 role source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_user_role"
|
||||
* id = "d7_user_role",
|
||||
* source_module = "user"
|
||||
* )
|
||||
*/
|
||||
class Role extends DrupalSqlBase {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
|
|||
* Drupal 7 user source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_user"
|
||||
* id = "d7_user",
|
||||
* source_module = "user"
|
||||
* )
|
||||
*/
|
||||
class User extends FieldableEntity {
|
||||
|
|
@ -61,18 +62,32 @@ class User extends FieldableEntity {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$uid = $row->getSourceProperty('uid');
|
||||
|
||||
$roles = $this->select('users_roles', 'ur')
|
||||
->fields('ur', ['rid'])
|
||||
->condition('ur.uid', $row->getSourceProperty('uid'))
|
||||
->condition('ur.uid', $uid)
|
||||
->execute()
|
||||
->fetchCol();
|
||||
$row->setSourceProperty('roles', $roles);
|
||||
|
||||
$row->setSourceProperty('data', unserialize($row->getSourceProperty('data')));
|
||||
|
||||
// If this entity was translated using Entity Translation, we need to get
|
||||
// its source language to get the field values in the right language.
|
||||
// The translations will be migrated by the d7_user_entity_translation
|
||||
// migration.
|
||||
$entity_translatable = $this->isEntityTranslatable('user');
|
||||
$source_language = $this->getEntityTranslationSourceLanguage('user', $uid);
|
||||
$language = $entity_translatable && $source_language ? $source_language : $row->getSourceProperty('language');
|
||||
$row->setSourceProperty('entity_language', $language);
|
||||
|
||||
// Get Field API field values.
|
||||
foreach (array_keys($this->getFields('user')) as $field) {
|
||||
$row->setSourceProperty($field, $this->getFieldValues('user', $field, $row->getSourceProperty('uid')));
|
||||
foreach ($this->getFields('user') as $field_name => $field) {
|
||||
// Ensure we're using the right language if the entity and the field are
|
||||
// translatable.
|
||||
$field_language = $entity_translatable && $field['translatable'] ? $language : NULL;
|
||||
$row->setSourceProperty($field_name, $this->getFieldValues('user', $field_name, $uid, NULL, $field_language));
|
||||
}
|
||||
|
||||
// Get profile field values. This code is lifted directly from the D6
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
|
||||
|
||||
/**
|
||||
* Provides Drupal 7 user entity translations source plugin.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_user_entity_translation",
|
||||
* source_module = "entity_translation"
|
||||
* )
|
||||
*/
|
||||
class UserEntityTranslation extends FieldableEntity {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
$query = $this->select('entity_translation', 'et')
|
||||
->fields('et')
|
||||
->condition('et.entity_type', 'user')
|
||||
->condition('et.source', '', '<>');
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$uid = $row->getSourceProperty('entity_id');
|
||||
$language = $row->getSourceProperty('language');
|
||||
|
||||
// Get Field API field values.
|
||||
foreach ($this->getFields('user') as $field_name => $field) {
|
||||
// Ensure we're using the right language if the entity is translatable.
|
||||
$field_language = $field['translatable'] ? $language : NULL;
|
||||
$row->setSourceProperty($field_name, $this->getFieldValues('user', $field_name, $uid, NULL, $field_language));
|
||||
}
|
||||
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return [
|
||||
'entity_type' => $this->t('The entity type this translation relates to'),
|
||||
'entity_id' => $this->t('The entity id this translation relates to'),
|
||||
'revision_id' => $this->t('The entity revision id this translation relates to'),
|
||||
'language' => $this->t('The target language for this translation.'),
|
||||
'source' => $this->t('The source language from which this translation was created.'),
|
||||
'uid' => $this->t('The author of this translation.'),
|
||||
'status' => $this->t('Boolean indicating whether the translation is published (visible to non-administrators).'),
|
||||
'translate' => $this->t('A boolean indicating whether this translation needs to be updated.'),
|
||||
'created' => $this->t('The Unix timestamp when the translation was created.'),
|
||||
'changed' => $this->t('The Unix timestamp when the translation was most recently saved.'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
return [
|
||||
'entity_id' => [
|
||||
'type' => 'integer',
|
||||
],
|
||||
'language' => [
|
||||
'type' => 'string',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -100,7 +100,6 @@ class Permission extends AccessPluginBase implements CacheableDependencyInterfac
|
|||
return $this->t($this->options['perm']);
|
||||
}
|
||||
|
||||
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
$options['perm'] = ['default' => 'access content'];
|
||||
|
|
|
|||
|
|
@ -96,7 +96,6 @@ class Role extends AccessPluginBase implements CacheableDependencyInterface {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
$options['role'] = ['default' => []];
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class Uid extends NumericArgument {
|
|||
protected $storage;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
* Constructs a \Drupal\user\Plugin\views\argument\Uid object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
|
|
@ -51,10 +51,10 @@ class Uid extends NumericArgument {
|
|||
* Override the behavior of title(). Get the name of the user.
|
||||
*
|
||||
* @return array
|
||||
* A list of usernames.
|
||||
* A list of usernames.
|
||||
*/
|
||||
public function titleQuery() {
|
||||
return array_map(function($account) {
|
||||
return array_map(function ($account) {
|
||||
return $account->label();
|
||||
}, $this->storage->loadMultiple($this->value));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class Permissions extends PrerenderList {
|
|||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
* Constructs a \Drupal\user\Plugin\views\field\Permissions object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class Roles extends PrerenderList {
|
|||
protected $database;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
* Constructs a \Drupal\user\Plugin\views\field\Roles object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
|
|
@ -82,7 +82,7 @@ class Roles extends PrerenderList {
|
|||
$ordered_roles = array_flip(array_keys($roles));
|
||||
foreach ($this->items as &$user_roles) {
|
||||
// Create an array of rids that the user has in the role weight order.
|
||||
$sorted_keys = array_intersect_key($ordered_roles, $user_roles);
|
||||
$sorted_keys = array_intersect_key($ordered_roles, $user_roles);
|
||||
// Merge with the unsorted array of role information which has the
|
||||
// effect of sorting it.
|
||||
$user_roles = array_merge($sorted_keys, $user_roles);
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
namespace Drupal\user\Plugin\views\field;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\system\Plugin\views\field\BulkForm;
|
||||
use Drupal\user\UserInterface;
|
||||
use Drupal\views\Plugin\views\field\BulkForm;
|
||||
|
||||
/**
|
||||
* Defines a user operations bulk form element.
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ class UserData extends FieldPluginBase {
|
|||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\user\Plugin\views\filter;
|
||||
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\views\Plugin\views\filter\BooleanOperator;
|
||||
|
|
@ -28,7 +29,7 @@ class Current extends BooleanOperator {
|
|||
$this->ensureMyTable();
|
||||
|
||||
$field = $this->tableAlias . '.' . $this->realField . ' ';
|
||||
$or = db_or();
|
||||
$or = new Condition('OR');
|
||||
|
||||
if (empty($this->value)) {
|
||||
$or->condition($field, '***CURRENT_USER***', '<>');
|
||||
|
|
|
|||
|
|
@ -115,7 +115,8 @@ class Name extends InOperator {
|
|||
$this->valueOptions[$account->id()] = $account->label();
|
||||
}
|
||||
else {
|
||||
$this->valueOptions[$account->id()] = 'Anonymous'; // Intentionally NOT translated.
|
||||
// Intentionally NOT translated.
|
||||
$this->valueOptions[$account->id()] = 'Anonymous';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,10 +74,20 @@ class Roles extends ManyToOne {
|
|||
*/
|
||||
public function calculateDependencies() {
|
||||
$dependencies = [];
|
||||
|
||||
if (in_array($this->operator, ['empty', 'not empty'])) {
|
||||
return $dependencies;
|
||||
}
|
||||
foreach ($this->value as $role_id) {
|
||||
|
||||
// The value might be a string due to the wrong plugin being used for role
|
||||
// field data, and subsequently the incorrect config schema object and
|
||||
// value. In the empty case stop early. Otherwise we cast it to an array
|
||||
// later.
|
||||
if (is_string($this->value) && $this->value === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
foreach ((array) $this->value as $role_id) {
|
||||
$role = $this->roleStorage->load($role_id);
|
||||
$dependencies[$role->getConfigDependencyKey()][] = $role->getConfigDependencyName();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ class Users extends WizardPluginBase {
|
|||
|
||||
/**
|
||||
* Set the created column.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $createdColumn = 'created';
|
||||
|
||||
|
|
@ -35,7 +37,7 @@ class Users extends WizardPluginBase {
|
|||
'plugin_id' => 'boolean',
|
||||
'entity_type' => 'user',
|
||||
'entity_field' => 'status',
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
Reference in a new issue