Move into nested docroot
This commit is contained in:
parent
83a0d3a149
commit
c8b70abde9
13405 changed files with 0 additions and 0 deletions
31
web/core/modules/user/src/Plugin/Action/AddRoleUser.php
Normal file
31
web/core/modules/user/src/Plugin/Action/AddRoleUser.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Action;
|
||||
|
||||
/**
|
||||
* Adds a role to a user.
|
||||
*
|
||||
* @Action(
|
||||
* id = "user_add_role_action",
|
||||
* label = @Translation("Add a role to the selected users"),
|
||||
* type = "user"
|
||||
* )
|
||||
*/
|
||||
class AddRoleUser extends ChangeUserRoleBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($account = NULL) {
|
||||
$rid = $this->configuration['rid'];
|
||||
// Skip adding the role to the user if they already have it.
|
||||
if ($account !== FALSE && !$account->hasRole($rid)) {
|
||||
// For efficiency manually save the original account before applying
|
||||
// any changes.
|
||||
$account->original = clone $account;
|
||||
$account->addRole($rid);
|
||||
$account->save();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
44
web/core/modules/user/src/Plugin/Action/BlockUser.php
Normal file
44
web/core/modules/user/src/Plugin/Action/BlockUser.php
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Action;
|
||||
|
||||
use Drupal\Core\Action\ActionBase;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
* Blocks a user.
|
||||
*
|
||||
* @Action(
|
||||
* id = "user_block_user_action",
|
||||
* label = @Translation("Block the selected users"),
|
||||
* type = "user"
|
||||
* )
|
||||
*/
|
||||
class BlockUser extends ActionBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($account = NULL) {
|
||||
// Skip blocking user if they are already blocked.
|
||||
if ($account !== FALSE && $account->isActive()) {
|
||||
// For efficiency manually save the original account before applying any
|
||||
// changes.
|
||||
$account->original = clone $account;
|
||||
$account->block();
|
||||
$account->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
/** @var \Drupal\user\UserInterface $object */
|
||||
$access = $object->status->access('edit', $account, TRUE)
|
||||
->andIf($object->access('update', $account, TRUE));
|
||||
|
||||
return $return_as_object ? $access : $access->isAllowed();
|
||||
}
|
||||
|
||||
}
|
||||
93
web/core/modules/user/src/Plugin/Action/CancelUser.php
Normal file
93
web/core/modules/user/src/Plugin/Action/CancelUser.php
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
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 Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Cancels a user account.
|
||||
*
|
||||
* @Action(
|
||||
* id = "user_cancel_user_action",
|
||||
* label = @Translation("Cancel the selected user accounts"),
|
||||
* type = "user",
|
||||
* confirm_form_route_name = "user.multiple_cancel_confirm"
|
||||
* )
|
||||
*/
|
||||
class CancelUser extends ActionBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The tempstore factory.
|
||||
*
|
||||
* @var \Drupal\user\PrivateTempStoreFactory
|
||||
*/
|
||||
protected $tempStoreFactory;
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
protected $currentUser;
|
||||
|
||||
/**
|
||||
* Constructs a DeleteNode object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin ID for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
|
||||
* The tempstore factory.
|
||||
* @param AccountInterface $current_user
|
||||
* Current user.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, PrivateTempStoreFactory $temp_store_factory, AccountInterface $current_user) {
|
||||
$this->currentUser = $current_user;
|
||||
$this->tempStoreFactory = $temp_store_factory;
|
||||
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('user.private_tempstore'),
|
||||
$container->get('current_user')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function executeMultiple(array $entities) {
|
||||
$this->tempStoreFactory->get('user_user_operations_cancel')->set($this->currentUser->id(), $entities);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($object = NULL) {
|
||||
$this->executeMultiple(array($object));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
/** @var \Drupal\user\UserInterface $object */
|
||||
return $object->access('delete', $account, $return_as_object);
|
||||
}
|
||||
|
||||
}
|
||||
102
web/core/modules/user/src/Plugin/Action/ChangeUserRoleBase.php
Normal file
102
web/core/modules/user/src/Plugin/Action/ChangeUserRoleBase.php
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Action;
|
||||
|
||||
use Drupal\Core\Action\ConfigurableActionBase;
|
||||
use Drupal\Core\Entity\DependencyTrait;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\user\RoleInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a base class for operations to change a user's role.
|
||||
*/
|
||||
abstract class ChangeUserRoleBase extends ConfigurableActionBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
use DependencyTrait;
|
||||
|
||||
/**
|
||||
* The user role entity type.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityTypeInterface
|
||||
*/
|
||||
protected $entityType;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeInterface $entity_type) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->entityType = $entity_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('entity.manager')->getDefinition('user_role')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function defaultConfiguration() {
|
||||
return array(
|
||||
'rid' => '',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$roles = user_role_names(TRUE);
|
||||
unset($roles[RoleInterface::AUTHENTICATED_ID]);
|
||||
$form['rid'] = array(
|
||||
'#type' => 'radios',
|
||||
'#title' => t('Role'),
|
||||
'#options' => $roles,
|
||||
'#default_value' => $this->configuration['rid'],
|
||||
'#required' => TRUE,
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
|
||||
$this->configuration['rid'] = $form_state->getValue('rid');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function calculateDependencies() {
|
||||
if (!empty($this->configuration['rid'])) {
|
||||
$prefix = $this->entityType->getConfigPrefix() . '.';
|
||||
$this->addDependency('config', $prefix . $this->configuration['rid']);
|
||||
}
|
||||
return $this->dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
/** @var \Drupal\user\UserInterface $object */
|
||||
$access = $object->access('update', $account, TRUE)
|
||||
->andIf($object->roles->access('edit', $account, TRUE));
|
||||
|
||||
return $return_as_object ? $access : $access->isAllowed();
|
||||
}
|
||||
|
||||
}
|
||||
31
web/core/modules/user/src/Plugin/Action/RemoveRoleUser.php
Normal file
31
web/core/modules/user/src/Plugin/Action/RemoveRoleUser.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Action;
|
||||
|
||||
/**
|
||||
* Removes a role from a user.
|
||||
*
|
||||
* @Action(
|
||||
* id = "user_remove_role_action",
|
||||
* label = @Translation("Remove a role from the selected users"),
|
||||
* type = "user"
|
||||
* )
|
||||
*/
|
||||
class RemoveRoleUser extends ChangeUserRoleBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($account = NULL) {
|
||||
$rid = $this->configuration['rid'];
|
||||
// Skip removing the role from the user if they already don't have it.
|
||||
if ($account !== FALSE && $account->hasRole($rid)) {
|
||||
// For efficiency manually save the original account before applying
|
||||
// any changes.
|
||||
$account->original = clone $account;
|
||||
$account->removeRole($rid);
|
||||
$account->save();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
41
web/core/modules/user/src/Plugin/Action/UnblockUser.php
Normal file
41
web/core/modules/user/src/Plugin/Action/UnblockUser.php
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Action;
|
||||
|
||||
use Drupal\Core\Action\ActionBase;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
* Unblocks a user.
|
||||
*
|
||||
* @Action(
|
||||
* id = "user_unblock_user_action",
|
||||
* label = @Translation("Unblock the selected users"),
|
||||
* type = "user"
|
||||
* )
|
||||
*/
|
||||
class UnblockUser extends ActionBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($account = NULL) {
|
||||
// Skip unblocking user if they are already unblocked.
|
||||
if ($account !== FALSE && $account->isBlocked()) {
|
||||
$account->activate();
|
||||
$account->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
/** @var \Drupal\user\UserInterface $object */
|
||||
$access = $object->status->access('edit', $account, TRUE)
|
||||
->andIf($object->access('update', $account, TRUE));
|
||||
|
||||
return $return_as_object ? $access : $access->isAllowed();
|
||||
}
|
||||
|
||||
}
|
||||
123
web/core/modules/user/src/Plugin/Block/UserLoginBlock.php
Normal file
123
web/core/modules/user/src/Plugin/Block/UserLoginBlock.php
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Block;
|
||||
|
||||
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;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a 'User login' block.
|
||||
*
|
||||
* @Block(
|
||||
* id = "user_login_block",
|
||||
* admin_label = @Translation("User login"),
|
||||
* category = @Translation("Forms")
|
||||
* )
|
||||
*/
|
||||
class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
use UrlGeneratorTrait;
|
||||
use RedirectDestinationTrait;
|
||||
|
||||
/**
|
||||
* The route match.
|
||||
*
|
||||
* @var \Drupal\Core\Routing\RouteMatchInterface
|
||||
*/
|
||||
protected $routeMatch;
|
||||
|
||||
/**
|
||||
* Constructs a new UserLoginBlock instance.
|
||||
*
|
||||
* @param array $configuration
|
||||
* The plugin configuration, i.e. an array with configuration values keyed
|
||||
* by configuration option name. The special key 'context' may be used to
|
||||
* initialize the defined contexts by setting it to an array of context
|
||||
* values keyed by context names.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
|
||||
* The route match.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteMatchInterface $route_match) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->routeMatch = $route_match;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('current_route_match')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function blockAccess(AccountInterface $account) {
|
||||
$route_name = $this->routeMatch->getRouteName();
|
||||
if ($account->isAnonymous() && !in_array($route_name, array('user.login', 'user.logout'))) {
|
||||
return AccessResult::allowed()
|
||||
->addCacheContexts(['route.name', 'user.roles:anonymous']);
|
||||
}
|
||||
return AccessResult::forbidden();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function build() {
|
||||
$form = \Drupal::formBuilder()->getForm('Drupal\user\Form\UserLoginForm');
|
||||
unset($form['name']['#attributes']['autofocus']);
|
||||
// When unsetting field descriptions, also unset aria-describedby attributes
|
||||
// to avoid introducing an accessibility bug.
|
||||
// @todo Do this automatically in https://www.drupal.org/node/2547063.
|
||||
unset($form['name']['#description']);
|
||||
unset($form['name']['#attributes']['aria-describedby']);
|
||||
unset($form['pass']['#description']);
|
||||
unset($form['pass']['#attributes']['aria-describedby']);
|
||||
$form['name']['#size'] = 15;
|
||||
$form['pass']['#size'] = 15;
|
||||
$form['#action'] = $this->url('<current>', [], ['query' => $this->getDestinationArray(), 'external' => FALSE]);
|
||||
// Build action links.
|
||||
$items = array();
|
||||
if (\Drupal::config('user.settings')->get('register') != USER_REGISTER_ADMINISTRATORS_ONLY) {
|
||||
$items['create_account'] = \Drupal::l($this->t('Create new account'), new Url('user.register', array(), array(
|
||||
'attributes' => array(
|
||||
'title' => $this->t('Create a new user account.'),
|
||||
'class' => array('create-account-link'),
|
||||
),
|
||||
)));
|
||||
}
|
||||
$items['request_password'] = \Drupal::l($this->t('Reset your password'), new Url('user.pass', array(), array(
|
||||
'attributes' => array(
|
||||
'title' => $this->t('Send password reset instructions via email.'),
|
||||
'class' => array('request-password-link'),
|
||||
),
|
||||
)));
|
||||
return array(
|
||||
'user_login_form' => $form,
|
||||
'user_links' => array(
|
||||
'#theme' => 'item_list',
|
||||
'#items' => $items,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
96
web/core/modules/user/src/Plugin/Condition/UserRole.php
Normal file
96
web/core/modules/user/src/Plugin/Condition/UserRole.php
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Condition;
|
||||
|
||||
use Drupal\Core\Condition\ConditionPluginBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Provides a 'User Role' condition.
|
||||
*
|
||||
* @Condition(
|
||||
* id = "user_role",
|
||||
* label = @Translation("User Role"),
|
||||
* context = {
|
||||
* "user" = @ContextDefinition("entity:user", label = @Translation("User"))
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class UserRole extends ConditionPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$form['roles'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => $this->t('When the user has the following roles'),
|
||||
'#default_value' => $this->configuration['roles'],
|
||||
'#options' => array_map('\Drupal\Component\Utility\Html::escape', user_role_names()),
|
||||
'#description' => $this->t('If you select no roles, the condition will evaluate to TRUE for all users.'),
|
||||
);
|
||||
return parent::buildConfigurationForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function defaultConfiguration() {
|
||||
return array(
|
||||
'roles' => array(),
|
||||
) + parent::defaultConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
|
||||
$this->configuration['roles'] = array_filter($form_state->getValue('roles'));
|
||||
parent::submitConfigurationForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function summary() {
|
||||
// Use the role labels. They will be sanitized below.
|
||||
$roles = array_intersect_key(user_role_names(), $this->configuration['roles']);
|
||||
if (count($roles) > 1) {
|
||||
$roles = implode(', ', $roles);
|
||||
}
|
||||
else {
|
||||
$roles = reset($roles);
|
||||
}
|
||||
if (!empty($this->configuration['negate'])) {
|
||||
return $this->t('The user is not a member of @roles', array('@roles' => $roles));
|
||||
}
|
||||
else {
|
||||
return $this->t('The user is a member of @roles', array('@roles' => $roles));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function evaluate() {
|
||||
if (empty($this->configuration['roles']) && !$this->isNegated()) {
|
||||
return TRUE;
|
||||
}
|
||||
$user = $this->getContextValue('user');
|
||||
return (bool) array_intersect($this->configuration['roles'], $user->getRoles());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheContexts() {
|
||||
// Optimize cache context, if a user cache context is provided, only use
|
||||
// user.roles, since that's the only part this condition cares about.
|
||||
$contexts = [];
|
||||
foreach (parent::getCacheContexts() as $context) {
|
||||
$contexts[] = $context == 'user' ? 'user.roles' : $context;
|
||||
}
|
||||
return $contexts;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,251 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\user\RoleInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides specific access control for the user entity type.
|
||||
*
|
||||
* @EntityReferenceSelection(
|
||||
* id = "default:user",
|
||||
* label = @Translation("User selection"),
|
||||
* entity_types = {"user"},
|
||||
* group = "default",
|
||||
* weight = 1
|
||||
* )
|
||||
*/
|
||||
class UserSelection extends DefaultSelection {
|
||||
|
||||
/**
|
||||
* The database connection.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* The user storage.
|
||||
*
|
||||
* @var \Drupal\user\UserStorageInterface
|
||||
*/
|
||||
protected $userStorage;
|
||||
|
||||
/**
|
||||
* Constructs a new UserSelection object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager service.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler service.
|
||||
* @param \Drupal\Core\Session\AccountInterface $current_user
|
||||
* The current user.
|
||||
* @param \Drupal\Core\Database\Connection $connection
|
||||
* The database connection.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, AccountInterface $current_user, Connection $connection) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_manager, $module_handler, $current_user);
|
||||
|
||||
$this->connection = $connection;
|
||||
$this->userStorage = $entity_manager->getStorage('user');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('entity.manager'),
|
||||
$container->get('module_handler'),
|
||||
$container->get('current_user'),
|
||||
$container->get('database')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$selection_handler_settings = $this->configuration['handler_settings'];
|
||||
|
||||
// Merge in default values.
|
||||
$selection_handler_settings += array(
|
||||
'filter' => array(
|
||||
'type' => '_none',
|
||||
),
|
||||
'include_anonymous' => TRUE,
|
||||
);
|
||||
|
||||
$form['include_anonymous'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Include the anonymous user.'),
|
||||
'#default_value' => $selection_handler_settings['include_anonymous'],
|
||||
);
|
||||
|
||||
// Add user specific filter options.
|
||||
$form['filter']['type'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => $this->t('Filter by'),
|
||||
'#options' => array(
|
||||
'_none' => $this->t('- None -'),
|
||||
'role' => $this->t('User role'),
|
||||
),
|
||||
'#ajax' => TRUE,
|
||||
'#limit_validation_errors' => array(),
|
||||
'#default_value' => $selection_handler_settings['filter']['type'],
|
||||
);
|
||||
|
||||
$form['filter']['settings'] = array(
|
||||
'#type' => 'container',
|
||||
'#attributes' => array('class' => array('entity_reference-settings')),
|
||||
'#process' => array(array('\Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem', 'formProcessMergeParent')),
|
||||
);
|
||||
|
||||
if ($selection_handler_settings['filter']['type'] == 'role') {
|
||||
// Merge in default values.
|
||||
$selection_handler_settings['filter'] += array(
|
||||
'role' => NULL,
|
||||
);
|
||||
|
||||
$form['filter']['settings']['role'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => $this->t('Restrict to the selected roles'),
|
||||
'#required' => TRUE,
|
||||
'#options' => array_diff_key(user_role_names(TRUE), array(RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID)),
|
||||
'#default_value' => $selection_handler_settings['filter']['role'],
|
||||
);
|
||||
}
|
||||
|
||||
$form += parent::buildConfigurationForm($form, $form_state);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
|
||||
$query = parent::buildEntityQuery($match, $match_operator);
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
|
||||
// Filter out the Anonymous user if the selection handler is configured to
|
||||
// exclude it.
|
||||
if (isset($handler_settings['include_anonymous']) && !$handler_settings['include_anonymous']) {
|
||||
$query->condition('uid', 0, '<>');
|
||||
}
|
||||
|
||||
// The user entity doesn't have a label column.
|
||||
if (isset($match)) {
|
||||
$query->condition('name', $match, $match_operator);
|
||||
}
|
||||
|
||||
// Filter by role.
|
||||
if (!empty($handler_settings['filter']['role'])) {
|
||||
$query->condition('roles', $handler_settings['filter']['role'], 'IN');
|
||||
}
|
||||
|
||||
// Adding the permission check is sadly insufficient for users: core
|
||||
// requires us to also know about the concept of 'blocked' and 'active'.
|
||||
if (!$this->currentUser->hasPermission('administer users')) {
|
||||
$query->condition('status', 1);
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createNewEntity($entity_type_id, $bundle, $label, $uid) {
|
||||
$user = parent::createNewEntity($entity_type_id, $bundle, $label, $uid);
|
||||
|
||||
// In order to create a referenceable user, it needs to be active.
|
||||
if (!$this->currentUser->hasPermission('administer users')) {
|
||||
/** @var \Drupal\user\UserInterface $user */
|
||||
$user->activate();
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
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) {
|
||||
/** @var \Drupal\user\UserInterface $user */
|
||||
return !empty(array_intersect($user->getRoles(), $this->configuration['handler_settings']['filter']['role']));
|
||||
});
|
||||
}
|
||||
if (!$this->currentUser->hasPermission('administer users')) {
|
||||
$entities = array_filter($entities, function ($user) {
|
||||
/** @var \Drupal\user\UserInterface $user */
|
||||
return $user->isActive();
|
||||
});
|
||||
}
|
||||
return $entities;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function entityQueryAlter(SelectInterface $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']) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->currentUser->hasPermission('administer users')) {
|
||||
// In addition, if the user is administrator, we need to make sure to
|
||||
// match the anonymous user, that doesn't actually have a name in the
|
||||
// database.
|
||||
$conditions = &$query->conditions();
|
||||
foreach ($conditions as $key => $condition) {
|
||||
if ($key !== '#conjunction' && is_string($condition['field']) && $condition['field'] === 'users_field_data.name') {
|
||||
// Remove the condition.
|
||||
unset($conditions[$key]);
|
||||
|
||||
// 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->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->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() + array(':anonymous_name' => \Drupal::config('user.settings')->get('anonymous')))
|
||||
->condition('base_table.uid', 0)
|
||||
);
|
||||
$query->condition($or);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\Plugin\Field\FieldFormatter\EntityReferenceFormatterBase;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'author' formatter.
|
||||
*
|
||||
* @FieldFormatter(
|
||||
* id = "author",
|
||||
* label = @Translation("Author"),
|
||||
* description = @Translation("Display the referenced author user entity."),
|
||||
* field_types = {
|
||||
* "entity_reference"
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class AuthorFormatter extends EntityReferenceFormatterBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = array();
|
||||
|
||||
foreach ($this->getEntitiesToView($items, $langcode) as $delta => $entity) {
|
||||
/** @var $referenced_user \Drupal\user\UserInterface */
|
||||
$elements[$delta] = array(
|
||||
'#theme' => 'username',
|
||||
'#account' => $entity,
|
||||
'#link_options' => array('attributes' => array('rel' => 'author')),
|
||||
'#cache' => array(
|
||||
'tags' => $entity->getCacheTags(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function isApplicable(FieldDefinitionInterface $field_definition) {
|
||||
return $field_definition->getFieldStorageDefinition()->getSetting('target_type') == 'user';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function checkAccess(EntityInterface $entity) {
|
||||
// Always allow an entity author's username to be read, even if the current
|
||||
// user does not have permission to view the entity author's profile.
|
||||
return AccessResult::allowed();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FormatterBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'user_name' formatter.
|
||||
*
|
||||
* @FieldFormatter(
|
||||
* id = "user_name",
|
||||
* label = @Translation("User name"),
|
||||
* description = @Translation("Display the user or author name."),
|
||||
* field_types = {
|
||||
* "string"
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class UserNameFormatter extends FormatterBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function defaultSettings() {
|
||||
$options = parent::defaultSettings();
|
||||
|
||||
$options['link_to_entity'] = TRUE;
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsForm(array $form, FormStateInterface $form_state) {
|
||||
$form = parent::settingsForm($form, $form_state);
|
||||
|
||||
$form['link_to_entity'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Link to the user'),
|
||||
'#default_value' => $this->getSetting('link_to_entity'),
|
||||
];
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = [];
|
||||
|
||||
foreach ($items as $delta => $item) {
|
||||
/** @var $user \Drupal\user\UserInterface */
|
||||
if ($user = $item->getEntity()) {
|
||||
if ($this->getSetting('link_to_entity')) {
|
||||
$elements[$delta] = [
|
||||
'#theme' => 'username',
|
||||
'#account' => $user,
|
||||
'#link_options' => ['attributes' => ['rel' => 'user']],
|
||||
'#cache' => [
|
||||
'tags' => $user->getCacheTags(),
|
||||
],
|
||||
];
|
||||
}
|
||||
else {
|
||||
$elements[$delta] = [
|
||||
'#markup' => $user->getDisplayName(),
|
||||
'#cache' => [
|
||||
'tags' => $user->getCacheTags(),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function isApplicable(FieldDefinitionInterface $field_definition) {
|
||||
return $field_definition->getTargetEntityTypeId() === 'user' && $field_definition->getName() === 'name';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\LanguageNegotiation;
|
||||
|
||||
use Drupal\language\LanguageNegotiationMethodBase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Class for identifying language from the user preferences.
|
||||
*
|
||||
* @LanguageNegotiation(
|
||||
* id = \Drupal\user\Plugin\LanguageNegotiation\LanguageNegotiationUser::METHOD_ID,
|
||||
* weight = -4,
|
||||
* name = @Translation("User"),
|
||||
* description = @Translation("Follow the user's language preference.")
|
||||
* )
|
||||
*/
|
||||
class LanguageNegotiationUser extends LanguageNegotiationMethodBase {
|
||||
|
||||
/**
|
||||
* The language negotiation method id.
|
||||
*/
|
||||
const METHOD_ID = 'language-user';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLangcode(Request $request = NULL) {
|
||||
$langcode = NULL;
|
||||
|
||||
// User preference (only for authenticated users).
|
||||
if ($this->languageManager && $this->currentUser->isAuthenticated()) {
|
||||
$preferred_langcode = $this->currentUser->getPreferredLangcode();
|
||||
$default_langcode = $this->languageManager->getDefaultLanguage()->getId();
|
||||
$languages = $this->languageManager->getLanguages();
|
||||
if (!empty($preferred_langcode) && $preferred_langcode != $default_langcode && isset($languages[$preferred_langcode])) {
|
||||
$langcode = $preferred_langcode;
|
||||
}
|
||||
}
|
||||
|
||||
// No language preference from the user.
|
||||
return $langcode;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\LanguageNegotiation;
|
||||
|
||||
use Drupal\Core\PathProcessor\PathProcessorManager;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Routing\AdminContext;
|
||||
use Drupal\Core\Routing\StackedRouteMatchInterface;
|
||||
use Drupal\language\LanguageNegotiationMethodBase;
|
||||
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
|
||||
|
||||
/**
|
||||
* Identifies admin language from the user preferences.
|
||||
*
|
||||
* @LanguageNegotiation(
|
||||
* id = Drupal\user\Plugin\LanguageNegotiation\LanguageNegotiationUserAdmin::METHOD_ID,
|
||||
* types = {Drupal\Core\Language\LanguageInterface::TYPE_INTERFACE},
|
||||
* weight = -10,
|
||||
* name = @Translation("Account administration pages"),
|
||||
* description = @Translation("Account administration pages language setting.")
|
||||
* )
|
||||
*/
|
||||
class LanguageNegotiationUserAdmin extends LanguageNegotiationMethodBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The language negotiation method id.
|
||||
*/
|
||||
const METHOD_ID = 'language-user-admin';
|
||||
|
||||
/**
|
||||
* The admin context.
|
||||
*
|
||||
* @var \Drupal\Core\Routing\AdminContext
|
||||
*/
|
||||
protected $adminContext;
|
||||
|
||||
/**
|
||||
* The router.
|
||||
*
|
||||
* This is only used when called from an event subscriber, before the request
|
||||
* has been populated with the route info.
|
||||
*
|
||||
* @var \Symfony\Component\Routing\Matcher\UrlMatcherInterface
|
||||
*/
|
||||
protected $router;
|
||||
|
||||
/**
|
||||
* The path processor manager.
|
||||
*
|
||||
* @var \Drupal\Core\PathProcessor\PathProcessorManager
|
||||
*/
|
||||
protected $pathProcessorManager;
|
||||
|
||||
/**
|
||||
* The stacked route match.
|
||||
*
|
||||
* @var \Drupal\Core\Routing\StackedRouteMatchInterface
|
||||
*/
|
||||
protected $stackedRouteMatch;
|
||||
|
||||
/**
|
||||
* Constructs a new LanguageNegotiationUserAdmin instance.
|
||||
*
|
||||
* @param \Drupal\Core\Routing\AdminContext $admin_context
|
||||
* The admin context.
|
||||
* @param \Symfony\Component\Routing\Matcher\UrlMatcherInterface $router
|
||||
* The router.
|
||||
* @param \Drupal\Core\PathProcessor\PathProcessorManager $path_processor_manager
|
||||
* The path processor manager.
|
||||
* @param \Drupal\Core\Routing\StackedRouteMatchInterface $stacked_route_match
|
||||
* The stacked route match.
|
||||
*/
|
||||
public function __construct(AdminContext $admin_context, UrlMatcherInterface $router, PathProcessorManager $path_processor_manager, StackedRouteMatchInterface $stacked_route_match) {
|
||||
$this->adminContext = $admin_context;
|
||||
$this->router = $router;
|
||||
$this->pathProcessorManager = $path_processor_manager;
|
||||
$this->stackedRouteMatch = $stacked_route_match;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$container->get('router.admin_context'),
|
||||
$container->get('router'),
|
||||
$container->get('path_processor_manager'),
|
||||
$container->get('current_route_match')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLangcode(Request $request = NULL) {
|
||||
$langcode = NULL;
|
||||
|
||||
// User preference (only for administrators).
|
||||
if ($this->currentUser->hasPermission('access administration pages') && ($preferred_admin_langcode = $this->currentUser->getPreferredAdminLangcode(FALSE)) && $this->isAdminPath($request)) {
|
||||
$langcode = $preferred_admin_langcode;
|
||||
}
|
||||
|
||||
// Not an admin, no admin language preference or not on an admin path.
|
||||
return $langcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given path is an administrative one.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The request object.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the path is administrative, FALSE otherwise.
|
||||
*/
|
||||
protected function isAdminPath(Request $request) {
|
||||
$result = FALSE;
|
||||
if ($request && $this->adminContext) {
|
||||
// If called from an event subscriber, the request may not have the route
|
||||
// object yet (it is still being built), so use the router to look up
|
||||
// based on the path.
|
||||
$route_match = $this->stackedRouteMatch->getRouteMatchFromRequest($request);
|
||||
if ($route_match && !$route_object = $route_match->getRouteObject()) {
|
||||
try {
|
||||
// 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);
|
||||
$attributes = $this->router->match($path);
|
||||
}
|
||||
catch (ResourceNotFoundException $e) {
|
||||
return FALSE;
|
||||
}
|
||||
catch (AccessDeniedHttpException $e) {
|
||||
return FALSE;
|
||||
}
|
||||
$route_object = $attributes[RouteObjectInterface::ROUTE_OBJECT];
|
||||
}
|
||||
$result = $this->adminContext->isAdminRoute($route_object);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Menu;
|
||||
|
||||
use Drupal\Core\Menu\MenuLinkDefault;
|
||||
use Drupal\Core\Menu\StaticMenuLinkOverridesInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* A menu link that shows "Log in" or "Log out" as appropriate.
|
||||
*/
|
||||
class LoginLogoutMenuLink extends MenuLinkDefault {
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
protected $currentUser;
|
||||
|
||||
/**
|
||||
* Constructs a new LoginLogoutMenuLink.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Menu\StaticMenuLinkOverridesInterface $static_override
|
||||
* The static override storage.
|
||||
* @param \Drupal\Core\Session\AccountInterface $current_user
|
||||
* The current user.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, StaticMenuLinkOverridesInterface $static_override, AccountInterface $current_user) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition, $static_override);
|
||||
|
||||
$this->currentUser = $current_user;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('menu_link.static.overrides'),
|
||||
$container->get('current_user')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTitle() {
|
||||
if ($this->currentUser->isAuthenticated()) {
|
||||
return $this->t('Log out');
|
||||
}
|
||||
else {
|
||||
return $this->t('Log in');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRouteName() {
|
||||
if ($this->currentUser->isAuthenticated()) {
|
||||
return 'user.logout';
|
||||
}
|
||||
else {
|
||||
return 'user.login';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheContexts() {
|
||||
return ['user.roles:authenticated'];
|
||||
}
|
||||
|
||||
}
|
||||
176
web/core/modules/user/src/Plugin/Search/UserSearch.php
Normal file
176
web/core/modules/user/src/Plugin/Search/UserSearch.php
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Search;
|
||||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Access\AccessibleInterface;
|
||||
use Drupal\search\Plugin\SearchPluginBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Executes a keyword search for users against the {users} database table.
|
||||
*
|
||||
* @SearchPlugin(
|
||||
* id = "user_search",
|
||||
* title = @Translation("Users")
|
||||
* )
|
||||
*/
|
||||
class UserSearch extends SearchPluginBase implements AccessibleInterface {
|
||||
|
||||
/**
|
||||
* The database connection.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected $database;
|
||||
|
||||
/**
|
||||
* The entity manager.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* The module handler.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
protected $currentUser;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
static public function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$container->get('database'),
|
||||
$container->get('entity.manager'),
|
||||
$container->get('module_handler'),
|
||||
$container->get('current_user'),
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a UserSearch object.
|
||||
*
|
||||
* @param Connection $database
|
||||
* The database connection.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param ModuleHandlerInterface $module_handler
|
||||
* The module handler.
|
||||
* @param \Drupal\Core\Session\AccountInterface $current_user
|
||||
* The current user.
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
*/
|
||||
public function __construct(Connection $database, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, AccountInterface $current_user, array $configuration, $plugin_id, $plugin_definition) {
|
||||
$this->database = $database;
|
||||
$this->entityManager = $entity_manager;
|
||||
$this->moduleHandler = $module_handler;
|
||||
$this->currentUser = $current_user;
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->addCacheTags(['user_list']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($operation = 'view', AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
$result = AccessResult::allowedIf(!empty($account) && $account->hasPermission('access user profiles'))->cachePerPermissions();
|
||||
return $return_as_object ? $result : $result->isAllowed();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute() {
|
||||
$results = array();
|
||||
if (!$this->isSearchExecutable()) {
|
||||
return $results;
|
||||
}
|
||||
|
||||
// Process the keywords.
|
||||
$keys = $this->keywords;
|
||||
// Escape for LIKE matching.
|
||||
$keys = $this->database->escapeLike($keys);
|
||||
// Replace wildcards with MySQL/PostgreSQL wildcards.
|
||||
$keys = preg_replace('!\*+!', '%', $keys);
|
||||
|
||||
// Run the query to find matching users.
|
||||
$query = $this->database
|
||||
->select('users_field_data', 'users')
|
||||
->extend('Drupal\Core\Database\Query\PagerSelectExtender');
|
||||
$query->fields('users', array('uid'));
|
||||
$query->condition('default_langcode', 1);
|
||||
if ($this->currentUser->hasPermission('administer users')) {
|
||||
// Administrators can also search in the otherwise private email field,
|
||||
// and they don't need to be restricted to only active users.
|
||||
$query->fields('users', array('mail'));
|
||||
$query->condition($query->orConditionGroup()
|
||||
->condition('name', '%' . $keys . '%', 'LIKE')
|
||||
->condition('mail', '%' . $keys . '%', 'LIKE')
|
||||
);
|
||||
}
|
||||
else {
|
||||
// Regular users can only search via usernames, and we do not show them
|
||||
// blocked accounts.
|
||||
$query->condition('name', '%' . $keys . '%', 'LIKE')
|
||||
->condition('status', 1);
|
||||
}
|
||||
$uids = $query
|
||||
->limit(15)
|
||||
->execute()
|
||||
->fetchCol();
|
||||
$accounts = $this->entityManager->getStorage('user')->loadMultiple($uids);
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$result = array(
|
||||
'title' => $account->getDisplayName(),
|
||||
'link' => $account->url('canonical', array('absolute' => TRUE)),
|
||||
);
|
||||
if ($this->currentUser->hasPermission('administer users')) {
|
||||
$result['title'] .= ' (' . $account->getEmail() . ')';
|
||||
}
|
||||
$this->addCacheableDependency($account);
|
||||
$results[] = $result;
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHelp() {
|
||||
$help = array('list' => array(
|
||||
'#theme' => 'item_list',
|
||||
'#items' => array(
|
||||
$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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Validation\Constraint;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
|
||||
/**
|
||||
* Checks if the plain text password is provided for editing a protected field.
|
||||
*
|
||||
* @Constraint(
|
||||
* id = "ProtectedUserField",
|
||||
* label = @Translation("Password required for protected field change", context = "Validation")
|
||||
* )
|
||||
*/
|
||||
class ProtectedUserFieldConstraint extends Constraint {
|
||||
|
||||
/**
|
||||
* Violation message.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $message = "Your current password is missing or incorrect; it's required to change the %name.";
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Validation\Constraint;
|
||||
|
||||
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
|
||||
use Drupal\Core\Session\AccountProxyInterface;
|
||||
use Drupal\user\UserStorageInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
|
||||
/**
|
||||
* Validates the ProtectedUserFieldConstraint constraint.
|
||||
*/
|
||||
class ProtectedUserFieldConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface {
|
||||
|
||||
/**
|
||||
* User storage handler.
|
||||
*
|
||||
* @var \Drupal\user\UserStorageInterface
|
||||
*/
|
||||
protected $userStorage;
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountProxyInterface
|
||||
*/
|
||||
protected $currentUser;
|
||||
|
||||
/**
|
||||
* Constructs the object.
|
||||
*
|
||||
* @param \Drupal\user\UserStorageInterface $user_storage
|
||||
* The user storage handler.
|
||||
* @param \Drupal\Core\Session\AccountProxyInterface $current_user
|
||||
* The current user.
|
||||
*/
|
||||
public function __construct(UserStorageInterface $user_storage, AccountProxyInterface $current_user) {
|
||||
$this->userStorage = $user_storage;
|
||||
$this->currentUser = $current_user;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager')->getStorage('user'),
|
||||
$container->get('current_user')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validate($items, Constraint $constraint) {
|
||||
if (!isset($items)) {
|
||||
return;
|
||||
}
|
||||
/* @var \Drupal\Core\Field\FieldItemListInterface $items */
|
||||
$field = $items->getFieldDefinition();
|
||||
|
||||
/* @var \Drupal\user\UserInterface $account */
|
||||
$account = $items->getEntity();
|
||||
if (!isset($account) || !empty($account->_skipProtectedUserFieldConstraint)) {
|
||||
// Looks like we are validating a field not being part of a user, or the
|
||||
// constraint should be skipped, so do nothing.
|
||||
return;
|
||||
}
|
||||
|
||||
// Only validate for existing entities and if this is the current user.
|
||||
if (!$account->isNew() && $account->id() == $this->currentUser->id()) {
|
||||
|
||||
/* @var \Drupal\user\UserInterface $account_unchanged */
|
||||
$account_unchanged = $this->userStorage
|
||||
->loadUnchanged($account->id());
|
||||
|
||||
$changed = FALSE;
|
||||
|
||||
// Special case for the password, it being empty means that the existing
|
||||
// password should not be changed, ignore empty password fields.
|
||||
$value = $items->value;
|
||||
if ($field->getName() != 'pass' || !empty($value)) {
|
||||
// Compare the values of the field this is being validated on.
|
||||
$changed = $items->getValue() != $account_unchanged->get($field->getName())->getValue();
|
||||
}
|
||||
if ($changed && (!$account->checkExistingPassword($account_unchanged))) {
|
||||
$this->context->addViolation($constraint->message, array('%name' => $field->getLabel()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Validation\Constraint;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidatorInterface;
|
||||
use Symfony\Component\Validator\ExecutionContextInterface;
|
||||
|
||||
/**
|
||||
* Checks if the user's email address is provided if required.
|
||||
*
|
||||
* The user mail field is NOT required if account originally had no mail set
|
||||
* and the user performing the edit has 'administer users' permission.
|
||||
* This allows users without email address to be edited and deleted.
|
||||
*
|
||||
* @Constraint(
|
||||
* id = "UserMailRequired",
|
||||
* label = @Translation("User email required", context = "Validation")
|
||||
* )
|
||||
*/
|
||||
class UserMailRequired extends Constraint implements ConstraintValidatorInterface {
|
||||
|
||||
/**
|
||||
* Violation message. Use the same message as FormValidator.
|
||||
*
|
||||
* Note that the name argument is not sanitized so that translators only have
|
||||
* one string to translate. The name is sanitized in self::validate().
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $message = '@name field is required.';
|
||||
|
||||
/**
|
||||
* @var \Symfony\Component\Validator\ExecutionContextInterface
|
||||
*/
|
||||
protected $context;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function initialize(ExecutionContextInterface $context) {
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validatedBy() {
|
||||
return get_class($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validate($items, Constraint $constraint) {
|
||||
/** @var \Drupal\Core\Field\FieldItemListInterface $items */
|
||||
/** @var \Drupal\user\UserInterface $account */
|
||||
$account = $items->getEntity();
|
||||
$existing_value = NULL;
|
||||
if ($account->id()) {
|
||||
$account_unchanged = \Drupal::entityManager()
|
||||
->getStorage('user')
|
||||
->loadUnchanged($account->id());
|
||||
$existing_value = $account_unchanged->getEmail();
|
||||
}
|
||||
|
||||
$required = !(!$existing_value && \Drupal::currentUser()->hasPermission('administer users'));
|
||||
|
||||
if ($required && (!isset($items) || $items->isEmpty())) {
|
||||
$this->context->addViolation($this->message, ['@name' => $account->getFieldDefinition('mail')->getLabel()]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Validation\Constraint;
|
||||
|
||||
use Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldConstraint;
|
||||
|
||||
/**
|
||||
* Checks if a user's email address is unique on the site.
|
||||
*
|
||||
* @Constraint(
|
||||
* id = "UserMailUnique",
|
||||
* label = @Translation("User email unique", context = "Validation")
|
||||
* )
|
||||
*/
|
||||
class UserMailUnique extends UniqueFieldConstraint {
|
||||
|
||||
public $message = 'The email address %value is already taken.';
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Validation\Constraint;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
|
||||
/**
|
||||
* Checks if a value is a valid user name.
|
||||
*
|
||||
* @Constraint(
|
||||
* id = "UserName",
|
||||
* label = @Translation("User name", context = "Validation"),
|
||||
* )
|
||||
*/
|
||||
class UserNameConstraint extends Constraint {
|
||||
|
||||
public $emptyMessage = 'You must enter a username.';
|
||||
public $spaceBeginMessage = 'The username cannot begin with a space.';
|
||||
public $spaceEndMessage = 'The username cannot end with a space.';
|
||||
public $multipleSpacesMessage = 'The username cannot contain multiple spaces in a row.';
|
||||
public $illegalMessage = 'The username contains an illegal character.';
|
||||
public $tooLongMessage = 'The username %name is too long: it must be %max characters or less.';
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Validation\Constraint;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
|
||||
/**
|
||||
* Validates the UserName constraint.
|
||||
*/
|
||||
class UserNameConstraintValidator extends ConstraintValidator {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validate($items, Constraint $constraint) {
|
||||
if (!isset($items) || !$items->value) {
|
||||
$this->context->addViolation($constraint->emptyMessage);
|
||||
return;
|
||||
}
|
||||
$name = $items->first()->value;
|
||||
if (substr($name, 0, 1) == ' ') {
|
||||
$this->context->addViolation($constraint->spaceBeginMessage);
|
||||
}
|
||||
if (substr($name, -1) == ' ') {
|
||||
$this->context->addViolation($constraint->spaceEndMessage);
|
||||
}
|
||||
if (strpos($name, ' ') !== FALSE) {
|
||||
$this->context->addViolation($constraint->multipleSpacesMessage);
|
||||
}
|
||||
if (preg_match('/[^\x{80}-\x{F7} a-z0-9@+_.\'-]/i', $name)
|
||||
|| preg_match(
|
||||
// Non-printable ISO-8859-1 + NBSP
|
||||
'/[\x{80}-\x{A0}' .
|
||||
// Soft-hyphen
|
||||
'\x{AD}' .
|
||||
// Various space characters
|
||||
'\x{2000}-\x{200F}' .
|
||||
// Bidirectional text overrides
|
||||
'\x{2028}-\x{202F}' .
|
||||
// Various text hinting characters
|
||||
'\x{205F}-\x{206F}' .
|
||||
// Byte order mark
|
||||
'\x{FEFF}' .
|
||||
// Full-width latin
|
||||
'\x{FF01}-\x{FF60}' .
|
||||
// Replacement characters
|
||||
'\x{FFF9}-\x{FFFD}' .
|
||||
// NULL byte and control characters
|
||||
'\x{0}-\x{1F}]/u',
|
||||
$name)
|
||||
) {
|
||||
$this->context->addViolation($constraint->illegalMessage);
|
||||
}
|
||||
if (Unicode::strlen($name) > USERNAME_MAX_LENGTH) {
|
||||
$this->context->addViolation($constraint->tooLongMessage, array('%name' => $name, '%max' => USERNAME_MAX_LENGTH));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\Validation\Constraint;
|
||||
|
||||
use Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldConstraint;
|
||||
|
||||
/**
|
||||
* Checks if a user name is unique on the site.
|
||||
*
|
||||
* @Constraint(
|
||||
* id = "UserNameUnique",
|
||||
* label = @Translation("User name unique", context = "Validation"),
|
||||
* )
|
||||
*/
|
||||
class UserNameUnique extends UniqueFieldConstraint {
|
||||
|
||||
public $message = 'The username %value is already taken.';
|
||||
|
||||
}
|
||||
48
web/core/modules/user/src/Plugin/migrate/ProfileValues.php
Normal file
48
web/core/modules/user/src/Plugin/migrate/ProfileValues.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate;
|
||||
|
||||
use Drupal\migrate\Exception\RequirementsException;
|
||||
use Drupal\migrate\Plugin\Migration;
|
||||
|
||||
/**
|
||||
* Plugin class for user migrations dealing with profile values.
|
||||
*/
|
||||
class ProfileValues extends Migration {
|
||||
|
||||
/**
|
||||
* Flag determining whether the process plugin has been initialized.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $init = FALSE;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProcess() {
|
||||
if (!$this->init) {
|
||||
$this->init = TRUE;
|
||||
$definition['source'] = [
|
||||
'plugin' => 'profile_field',
|
||||
'ignore_map' => TRUE,
|
||||
] + $this->source;
|
||||
$definition['destination']['plugin'] = 'null';
|
||||
try {
|
||||
$profile_field_migration = $this->migrationPluginManager->createStubMigration($definition);
|
||||
$source_plugin = $profile_field_migration->getSourcePlugin();
|
||||
$source_plugin->checkRequirements();
|
||||
foreach ($source_plugin as $row) {
|
||||
$name = $row->getSourceProperty('name');
|
||||
$this->process[$name] = $name;
|
||||
}
|
||||
}
|
||||
catch (RequirementsException $e) {
|
||||
// The checkRequirements() call will fail when the profile module does
|
||||
// not exist on the source site.
|
||||
}
|
||||
}
|
||||
return parent::getProcess();
|
||||
}
|
||||
|
||||
}
|
||||
64
web/core/modules/user/src/Plugin/migrate/User.php
Normal file
64
web/core/modules/user/src/Plugin/migrate/User.php
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate;
|
||||
|
||||
use Drupal\migrate\Exception\RequirementsException;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\CckMigration;
|
||||
|
||||
/**
|
||||
* Plugin class for Drupal 7 user migrations dealing with fields and profiles.
|
||||
*/
|
||||
class User extends CckMigration {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProcess() {
|
||||
if (!$this->init) {
|
||||
$this->init = TRUE;
|
||||
$definition['source'] = [
|
||||
'entity_type' => 'user',
|
||||
'ignore_map' => TRUE,
|
||||
] + $this->source;
|
||||
$definition['destination']['plugin'] = 'null';
|
||||
if (\Drupal::moduleHandler()->moduleExists('field')) {
|
||||
$definition['source']['plugin'] = 'd7_field_instance';
|
||||
$field_migration = $this->migrationPluginManager->createStubMigration($definition);
|
||||
foreach ($field_migration->getSourcePlugin() as $row) {
|
||||
$field_name = $row->getSourceProperty('field_name');
|
||||
$field_type = $row->getSourceProperty('type');
|
||||
if (empty($field_type)) {
|
||||
continue;
|
||||
}
|
||||
if ($this->cckPluginManager->hasDefinition($field_type)) {
|
||||
if (!isset($this->cckPluginCache[$field_type])) {
|
||||
$this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($field_type, [], $this);
|
||||
}
|
||||
$info = $row->getSource();
|
||||
$this->cckPluginCache[$field_type]
|
||||
->processCckFieldValues($this, $field_name, $info);
|
||||
}
|
||||
else {
|
||||
$this->process[$field_name] = $field_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
$definition['source']['plugin'] = 'profile_field';
|
||||
$profile_migration = $this->migrationPluginManager->createStubMigration($definition);
|
||||
// Ensure that Profile is enabled in the source DB.
|
||||
$profile_migration->checkRequirements();
|
||||
foreach ($profile_migration->getSourcePlugin() as $row) {
|
||||
$name = $row->getSourceProperty('name');
|
||||
$this->process[$name] = $name;
|
||||
}
|
||||
}
|
||||
catch (RequirementsException $e) {
|
||||
// The checkRequirements() call will fail when the profile module does
|
||||
// not exist on the source site.
|
||||
}
|
||||
}
|
||||
return parent::getProcess();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
<?php
|
||||
|
||||
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;
|
||||
use Drupal\Core\Field\FieldTypePluginManagerInterface;
|
||||
use Drupal\Core\Field\Plugin\Field\FieldType\EmailItem;
|
||||
use Drupal\Core\Password\PasswordInterface;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
|
||||
use Drupal\migrate\Row;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* @MigrateDestination(
|
||||
* id = "entity:user"
|
||||
* )
|
||||
*/
|
||||
class EntityUser extends EntityContentBase {
|
||||
|
||||
/**
|
||||
* The password service class.
|
||||
*
|
||||
* @var \Drupal\Core\Password\PasswordInterface
|
||||
*/
|
||||
protected $password;
|
||||
|
||||
/**
|
||||
* Builds an user entity destination.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
|
||||
* The migration.
|
||||
* @param EntityStorageInterface $storage
|
||||
* The storage for this entity type.
|
||||
* @param array $bundles
|
||||
* The list of bundles this entity type has.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager service.
|
||||
* @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager
|
||||
* The field type plugin manager service.
|
||||
* @param \Drupal\Core\Password\PasswordInterface $password
|
||||
* The password service.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, EntityManagerInterface $entity_manager, FieldTypePluginManagerInterface $field_type_manager, PasswordInterface $password) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $entity_manager, $field_type_manager);
|
||||
$this->password = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
|
||||
$entity_type = static::getEntityTypeId($plugin_id);
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$migration,
|
||||
$container->get('entity.manager')->getStorage($entity_type),
|
||||
array_keys($container->get('entity.manager')->getBundleInfo($entity_type)),
|
||||
$container->get('entity.manager'),
|
||||
$container->get('plugin.manager.field.field_type'),
|
||||
$container->get('password')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @throws \Drupal\migrate\MigrateException
|
||||
*/
|
||||
public function import(Row $row, array $old_destination_id_values = array()) {
|
||||
// Do not overwrite the root account password.
|
||||
if ($row->getDestinationProperty('uid') == 1) {
|
||||
$row->removeDestinationProperty('pass');
|
||||
}
|
||||
return parent::import($row, $old_destination_id_values);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function save(ContentEntityInterface $entity, array $old_destination_id_values = array()) {
|
||||
// Do not overwrite the root account password.
|
||||
if ($entity->id() != 1) {
|
||||
// Set the pre_hashed password so that the PasswordItem field does not hash
|
||||
// already hashed passwords. If the md5_passwords configuration option is
|
||||
// set we need to rehash the password and prefix with a U.
|
||||
// @see \Drupal\Core\Field\Plugin\Field\FieldType\PasswordItem::preSave()
|
||||
$entity->pass->pre_hashed = TRUE;
|
||||
if (isset($this->configuration['md5_passwords'])) {
|
||||
$entity->pass->value = 'U' . $this->password->hash($entity->pass->value);
|
||||
}
|
||||
}
|
||||
return parent::save($entity, $old_destination_id_values);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processStubRow(Row $row) {
|
||||
parent::processStubRow($row);
|
||||
// Email address is not defined as required in the base field definition but
|
||||
// is effectively required by the UserMailRequired constraint. This means
|
||||
// that Entity::processStubRow() did not populate it - we do it here.
|
||||
$field_definitions = $this->entityManager
|
||||
->getFieldDefinitions($this->storage->getEntityTypeId(),
|
||||
$this->getKey('bundle'));
|
||||
$mail = EmailItem::generateSampleValue($field_definitions['mail']);
|
||||
$row->setDestinationProperty('mail', reset($mail));
|
||||
|
||||
// @todo Work-around for https://www.drupal.org/node/2602066.
|
||||
$name = $row->getDestinationProperty('name');
|
||||
if (is_array($name)) {
|
||||
$name = reset($name);
|
||||
}
|
||||
if (Unicode::strlen($name) > USERNAME_MAX_LENGTH) {
|
||||
$row->setDestinationProperty('name', Unicode::substr($name, 0, USERNAME_MAX_LENGTH));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\destination;
|
||||
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\user\UserData as UserDataStorage;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate\Plugin\migrate\destination\DestinationBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
|
||||
/**
|
||||
* @MigrateDestination(
|
||||
* id = "user_data"
|
||||
* )
|
||||
*/
|
||||
class UserData extends DestinationBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* @var \Drupal\user\UserData
|
||||
*/
|
||||
protected $userData;
|
||||
|
||||
/**
|
||||
* Builds an user data entity destination.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
|
||||
* The migration.
|
||||
* @param \Drupal\user\UserData $user_data
|
||||
* The user data service.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, UserDataStorage $user_data) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration);
|
||||
$this->userData = $user_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$migration,
|
||||
$container->get('user.data')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function import(Row $row, array $old_destination_id_values = array()) {
|
||||
$uid = $row->getDestinationProperty('uid');
|
||||
$module = $row->getDestinationProperty('module');
|
||||
$key = $row->getDestinationProperty('key');
|
||||
$this->userData->set($module, $uid, $key, $row->getDestinationProperty('settings'));
|
||||
|
||||
return [$uid, $module, $key];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['uid']['type'] = 'integer';
|
||||
$ids['module']['type'] = 'string';
|
||||
$ids['key']['type'] = 'string';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields(MigrationInterface $migration = NULL) {
|
||||
return [
|
||||
'uid' => 'The user id.',
|
||||
'module' => 'The module name responsible for the settings.',
|
||||
'key' => 'The setting key to save under.',
|
||||
'settings' => 'The settings to save.',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\process;
|
||||
|
||||
use Drupal\migrate\MigrateException;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* Plugin to replace !tokens with [tokens].
|
||||
*
|
||||
* @MigrateProcessPlugin(
|
||||
* id = "convert_tokens",
|
||||
* handle_multiples = TRUE
|
||||
* )
|
||||
*/
|
||||
class ConvertTokens extends ProcessPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
$tokens = array(
|
||||
'!site' => '[site:name]',
|
||||
'!username' => '[user:name]',
|
||||
'!mailto' => '[user:mail]',
|
||||
'!login_uri' => '[site:login-url]',
|
||||
'!uri_brief' => '[site:url-brief]',
|
||||
'!edit_uri' => '[user:edit-url]',
|
||||
'!login_url' => '[user:one-time-login-url]',
|
||||
'!uri' => '[site:url]',
|
||||
'!date' => '[date:medium]',
|
||||
'!password' => '',
|
||||
);
|
||||
|
||||
// Given that our source is a database column that could hold a NULL
|
||||
// value, sometimes that filters down to here. str_replace() cannot
|
||||
// handle NULLs as the subject, so we reset to an empty string.
|
||||
if (is_null($value)) {
|
||||
$value = '';
|
||||
}
|
||||
|
||||
if (is_string($value)) {
|
||||
return str_replace(array_keys($tokens), $tokens, $value);
|
||||
}
|
||||
else {
|
||||
throw new MigrateException('Value must be a string.');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\process;
|
||||
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* @MigrateProcessPlugin(
|
||||
* id = "profile_field_settings"
|
||||
* )
|
||||
*/
|
||||
class ProfileFieldSettings extends ProcessPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function transform($type, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
$settings = array();
|
||||
switch ($type) {
|
||||
case 'date':
|
||||
$settings['datetime_type'] = 'date';
|
||||
break;
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\process;
|
||||
|
||||
use Drupal\Core\Language\LanguageManager;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Row;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a process plugin for the user langcode.
|
||||
*
|
||||
* @MigrateProcessPlugin(
|
||||
* id = "user_langcode"
|
||||
* )
|
||||
*/
|
||||
class UserLangcode extends ProcessPluginBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The language manager.
|
||||
*
|
||||
* @var \Drupal\Core\Language\LanguageManager
|
||||
*/
|
||||
protected $languageManager;
|
||||
|
||||
/**
|
||||
* Constructs a UserLangcode object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* Plugin configuration.
|
||||
* @param string $plugin_id
|
||||
* The plugin ID.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin definiiton.
|
||||
* @param \Drupal\Core\Language\LanguageManager $language_manager
|
||||
* The language manager service.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, LanguageManager $language_manager) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->languageManager = $language_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('language_manager')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
if (!isset($this->configuration['fallback_to_site_default'])) {
|
||||
$this->configuration['fallback_to_site_default'] = TRUE;
|
||||
}
|
||||
|
||||
// If the user's language is empty, it means the locale module was not
|
||||
// installed, so the user's langcode should be English and the user's
|
||||
// preferred_langcode and preferred_admin_langcode should fallback to the
|
||||
// default language.
|
||||
if (empty($value)) {
|
||||
if ($this->configuration['fallback_to_site_default']) {
|
||||
return $this->languageManager->getDefaultLanguage()->getId();
|
||||
}
|
||||
else {
|
||||
return 'en';
|
||||
}
|
||||
}
|
||||
// If the user's language does not exists, use the default language.
|
||||
elseif ($this->languageManager->getLanguage($value) === NULL) {
|
||||
return $this->languageManager->getDefaultLanguage()->getId();
|
||||
}
|
||||
|
||||
// If the langcode is a valid one, just return it.
|
||||
return $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\process;
|
||||
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* Keep the predefined roles for rid 1 and 2.
|
||||
*
|
||||
* @MigrateProcessPlugin(
|
||||
* id = "user_update_8002"
|
||||
* )
|
||||
*/
|
||||
class UserUpdate8002 extends ProcessPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Keep the predefined roles for rid 1 and 2.
|
||||
*/
|
||||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
$rid = $row->getSourceProperty('rid');
|
||||
$map = array(
|
||||
1 => 'anonymous',
|
||||
2 => 'authenticated',
|
||||
);
|
||||
return isset($map[$rid]) ? $map[$rid] : $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\process\d6;
|
||||
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\Core\Config\Config;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Converts user time zones from time zone offsets to time zone names.
|
||||
*
|
||||
* @MigrateProcessPlugin(
|
||||
* id = "user_update_7002"
|
||||
* )
|
||||
*/
|
||||
class UserUpdate7002 extends ProcessPluginBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* System timezones.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $timezones;
|
||||
|
||||
/**
|
||||
* Contains the system.theme configuration object.
|
||||
*
|
||||
* @var \Drupal\Core\Config\Config
|
||||
*/
|
||||
protected $dateConfig;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, array $plugin_definition, Config $date_config) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->dateConfig = $date_config;
|
||||
if (!isset(static::$timezones)) {
|
||||
static::$timezones = system_time_zones();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('config.factory')->get('system.date')
|
||||
);
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
$timezone = NULL;
|
||||
|
||||
if ($row->hasSourceProperty('timezone_name')) {
|
||||
if (isset(static::$timezones[$row->getSourceProperty('timezone_name')])) {
|
||||
$timezone = $row->getSourceProperty('timezone_name');
|
||||
}
|
||||
}
|
||||
if (!$timezone && $row->hasSourceProperty('event_timezone')) {
|
||||
if (isset(static::$timezones[$row->getSourceProperty('event_timezone')])) {
|
||||
$timezone = $row->getSourceProperty('event_timezone');
|
||||
}
|
||||
}
|
||||
|
||||
if ($timezone === NULL) {
|
||||
$timezone = $this->dateConfig->get('timezone.default');
|
||||
}
|
||||
return $timezone;
|
||||
}
|
||||
|
||||
}
|
||||
108
web/core/modules/user/src/Plugin/migrate/source/ProfileField.php
Normal file
108
web/core/modules/user/src/Plugin/migrate/source/ProfileField.php
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\source;
|
||||
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* Profile field source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "profile_field",
|
||||
* source_provider = "profile"
|
||||
* )
|
||||
*/
|
||||
class ProfileField extends DrupalSqlBase {
|
||||
|
||||
/**
|
||||
* The source table containing profile field info.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldTable;
|
||||
|
||||
/**
|
||||
* The source table containing the profile values.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $valueTable;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
if (empty($this->fieldTable) || empty($this->valueTable)) {
|
||||
if ($this->getModuleSchemaVersion('system') >= 7000) {
|
||||
$this->fieldTable = 'profile_field';
|
||||
$this->valueTable = 'profile_value';
|
||||
}
|
||||
else {
|
||||
$this->fieldTable = 'profile_fields';
|
||||
$this->valueTable = 'profile_values';
|
||||
}
|
||||
}
|
||||
return $this->select($this->fieldTable, 'pf')->fields('pf');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
if ($row->getSourceProperty('type') == 'selection') {
|
||||
// Get the current options.
|
||||
$current_options = preg_split("/[\r\n]+/", $row->getSourceProperty('options'));
|
||||
// Select the list values from the profile_values table to ensure we get
|
||||
// them all since they can get out of sync with profile_fields.
|
||||
$options = $this->select($this->valueTable, 'pv')
|
||||
->distinct()
|
||||
->fields('pv', ['value'])
|
||||
->condition('fid', $row->getSourceProperty('fid'))
|
||||
->execute()
|
||||
->fetchCol();
|
||||
$options = array_merge($current_options, $options);
|
||||
// array_combine() takes care of any duplicates options.
|
||||
$row->setSourceProperty('options', array_combine($options, $options));
|
||||
}
|
||||
|
||||
if ($row->getSourceProperty('type') == 'checkbox') {
|
||||
// D6 profile checkboxes values are always 0 or 1 (with no labels), so we
|
||||
// need to create two label-less options that will get 0 and 1 for their
|
||||
// keys.
|
||||
$row->setSourceProperty('options', array(NULL, NULL));
|
||||
}
|
||||
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return array(
|
||||
'fid' => $this->t('Primary Key: Unique profile field ID.'),
|
||||
'title' => $this->t('Title of the field shown to the end user.'),
|
||||
'name' => $this->t('Internal name of the field used in the form HTML and URLs.'),
|
||||
'explanation' => $this->t('Explanation of the field to end users.'),
|
||||
'category' => $this->t('Profile category that the field will be grouped under.'),
|
||||
'page' => $this->t("Title of page used for browsing by the field's value"),
|
||||
'type' => $this->t('Type of form field.'),
|
||||
'weight' => $this->t('Weight of field in relation to other profile fields.'),
|
||||
'required' => $this->t('Whether the user is required to enter a value. (0 = no, 1 = yes)'),
|
||||
'register' => $this->t('Whether the field is visible in the user registration form. (1 = yes, 0 = no)'),
|
||||
'visibility' => $this->t('The level of visibility for the field. (0 = hidden, 1 = private, 2 = public on profile but not member list pages, 3 = public on profile and list pages)'),
|
||||
'autocomplete' => $this->t('Whether form auto-completion is enabled. (0 = disabled, 1 = enabled)'),
|
||||
'options' => $this->t('List of options to be used in a list selection field.'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['fid']['type'] = 'integer';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\source;
|
||||
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
use Drupal\migrate\Plugin\migrate\source\DummyQueryTrait;
|
||||
|
||||
/**
|
||||
* User picture field instance source.
|
||||
*
|
||||
* @todo Support default picture?
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "user_picture_instance"
|
||||
* )
|
||||
*/
|
||||
class UserPictureInstance extends DrupalSqlBase {
|
||||
|
||||
use DummyQueryTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function initializeIterator() {
|
||||
return new \ArrayIterator(array(
|
||||
array(
|
||||
'id' => '',
|
||||
'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'),
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return array(
|
||||
'file_directory' => 'The directory to store images..',
|
||||
'max_filesize' => 'The maximum allowed file size in KBs.',
|
||||
'max_resolution' => "The maximum resolution.",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['id']['type'] = 'string';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
|
||||
/**
|
||||
* Drupal 6 profile fields values source.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_profile_field_values",
|
||||
* source_provider = "profile"
|
||||
* )
|
||||
*/
|
||||
class ProfileFieldValues extends DrupalSqlBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
$query = $this->select('profile_values', 'pv')
|
||||
->distinct()
|
||||
->fields('pv', array('uid'));
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
// Find profile values for this row.
|
||||
$query = $this->select('profile_values', 'pv')
|
||||
->fields('pv', array('fid', 'value'));
|
||||
$query->leftJoin('profile_fields', 'pf', 'pf.fid=pv.fid');
|
||||
$query->fields('pf', array('name', 'type'));
|
||||
$query->condition('uid', $row->getSourceProperty('uid'));
|
||||
$results = $query->execute();
|
||||
|
||||
foreach ($results as $profile_value) {
|
||||
// Check special case for date. We need to unserialize.
|
||||
if ($profile_value['type'] == 'date') {
|
||||
$date = unserialize($profile_value['value']);
|
||||
$date = date('Y-m-d', mktime(0, 0, 0, $date['month'], $date['day'], $date['year']));
|
||||
$row->setSourceProperty($profile_value['name'], array('value' => $date));
|
||||
}
|
||||
elseif ($profile_value['type'] == 'list') {
|
||||
// Explode by newline and comma.
|
||||
$row->setSourceProperty($profile_value['name'], preg_split("/[\r\n,]+/", $profile_value['value']));
|
||||
}
|
||||
else {
|
||||
$row->setSourceProperty($profile_value['name'], array($profile_value['value']));
|
||||
}
|
||||
}
|
||||
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
$fields = array(
|
||||
'fid' => $this->t('Unique profile field ID.'),
|
||||
'uid' => $this->t('The user Id.'),
|
||||
'value' => $this->t('The value for this field.'),
|
||||
);
|
||||
|
||||
$query = $this->select('profile_values', 'pv')
|
||||
->fields('pv', array('fid', 'value'));
|
||||
$query->leftJoin('profile_fields', 'pf', 'pf.fid=pv.fid');
|
||||
$query->fields('pf', array('name', 'title'));
|
||||
$results = $query->execute();
|
||||
foreach ($results as $profile) {
|
||||
$fields[$profile['name']] = $this->t($profile['title']);
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
return array(
|
||||
'uid' => array(
|
||||
'type' => 'integer',
|
||||
'alias' => 'pv',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
95
web/core/modules/user/src/Plugin/migrate/source/d6/Role.php
Normal file
95
web/core/modules/user/src/Plugin/migrate/source/d6/Role.php
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
|
||||
/**
|
||||
* Drupal 6 role source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_user_role"
|
||||
* )
|
||||
*/
|
||||
class Role extends DrupalSqlBase {
|
||||
|
||||
/**
|
||||
* List of filter IDs per role IDs.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $filterPermissions = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
$query = $this->select('role', 'r')
|
||||
->fields('r', array('rid', 'name'))
|
||||
->orderBy('r.rid');
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return array(
|
||||
'rid' => $this->t('Role ID.'),
|
||||
'name' => $this->t('The name of the user role.'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initializeIterator() {
|
||||
$filter_roles = $this->select('filter_formats', 'f')
|
||||
->fields('f', array('format', 'roles'))
|
||||
->execute()
|
||||
->fetchAllKeyed();
|
||||
foreach ($filter_roles as $format => $roles) {
|
||||
// Drupal 6 code: $roles = ','. implode(',', $roles) .',';
|
||||
// Remove the beginning and ending comma.
|
||||
foreach (explode(',', trim($roles, ',')) as $rid) {
|
||||
$this->filterPermissions[$rid][] = $format;
|
||||
}
|
||||
}
|
||||
return parent::initializeIterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$rid = $row->getSourceProperty('rid');
|
||||
$permissions = $this->select('permission', 'p')
|
||||
->fields('p', array('perm'))
|
||||
->condition('rid', $rid)
|
||||
->execute()
|
||||
->fetchField();
|
||||
|
||||
// If a role has no permissions then set to an empty array. The role will
|
||||
// be migrated and given the default D8 permissions.
|
||||
if ($permissions) {
|
||||
$row->setSourceProperty('permissions', explode(', ', $permissions));
|
||||
}
|
||||
else {
|
||||
$row->setSourceProperty('permissions', []);
|
||||
}
|
||||
if (isset($this->filterPermissions[$rid])) {
|
||||
$row->setSourceProperty("filter_permissions:$rid", $this->filterPermissions[$rid]);
|
||||
}
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['rid']['type'] = 'integer';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
}
|
||||
132
web/core/modules/user/src/Plugin/migrate/source/d6/User.php
Normal file
132
web/core/modules/user/src/Plugin/migrate/source/d6/User.php
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
|
||||
/**
|
||||
* Drupal 6 user source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_user"
|
||||
* )
|
||||
*/
|
||||
class User extends DrupalSqlBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
return $this->select('users', 'u')
|
||||
->fields('u', array_keys($this->baseFields()))
|
||||
->condition('u.uid', 0, '>');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
$fields = $this->baseFields();
|
||||
|
||||
// Add roles field.
|
||||
$fields['roles'] = $this->t('Roles');
|
||||
|
||||
// Profile fields.
|
||||
if ($this->moduleExists('profile')) {
|
||||
$fields += $this->select('profile_fields', 'pf')
|
||||
->fields('pf', array('name', 'title'))
|
||||
->execute()
|
||||
->fetchAllKeyed();
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
// User roles.
|
||||
$roles = $this->select('users_roles', 'ur')
|
||||
->fields('ur', array('rid'))
|
||||
->condition('ur.uid', $row->getSourceProperty('uid'))
|
||||
->execute()
|
||||
->fetchCol();
|
||||
$row->setSourceProperty('roles', $roles);
|
||||
|
||||
// We are adding here the Event contributed module column.
|
||||
// @see https://api.drupal.org/api/drupal/modules%21user%21user.install/function/user_update_7002/7
|
||||
if ($row->hasSourceProperty('timezone_id') && $row->getSourceProperty('timezone_id')) {
|
||||
if ($this->getDatabase()->schema()->tableExists('event_timezones')) {
|
||||
$event_timezone = $this->select('event_timezones', 'e')
|
||||
->fields('e', array('name'))
|
||||
->condition('e.timezone', $row->getSourceProperty('timezone_id'))
|
||||
->execute()
|
||||
->fetchField();
|
||||
if ($event_timezone) {
|
||||
$row->setSourceProperty('event_timezone', $event_timezone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unserialize Data.
|
||||
$row->setSourceProperty('data', unserialize($row->getSourceProperty('data')));
|
||||
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
return array(
|
||||
'uid' => array(
|
||||
'type' => 'integer',
|
||||
'alias' => 'u',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user base fields to be migrated.
|
||||
*
|
||||
* @return array
|
||||
* Associative array having field name as key and description as value.
|
||||
*/
|
||||
protected function baseFields() {
|
||||
$fields = array(
|
||||
'uid' => $this->t('User ID'),
|
||||
'name' => $this->t('Username'),
|
||||
'pass' => $this->t('Password'),
|
||||
'mail' => $this->t('Email address'),
|
||||
'theme' => $this->t('Theme'),
|
||||
'signature' => $this->t('Signature'),
|
||||
'signature_format' => $this->t('Signature format'),
|
||||
'created' => $this->t('Registered timestamp'),
|
||||
'access' => $this->t('Last access timestamp'),
|
||||
'login' => $this->t('Last login timestamp'),
|
||||
'status' => $this->t('Status'),
|
||||
'timezone' => $this->t('Timezone'),
|
||||
'language' => $this->t('Language'),
|
||||
'picture' => $this->t('Picture'),
|
||||
'init' => $this->t('Init'),
|
||||
'data' => $this->t('User data'),
|
||||
);
|
||||
|
||||
// Possible field added by Date contributed module.
|
||||
// @see https://api.drupal.org/api/drupal/modules%21user%21user.install/function/user_update_7002/7
|
||||
if ($this->getDatabase()->schema()->fieldExists('users', 'timezone_name')) {
|
||||
$fields['timezone_name'] = $this->t('Timezone (Date)');
|
||||
}
|
||||
|
||||
// Possible field added by Event contributed module.
|
||||
// @see https://api.drupal.org/api/drupal/modules%21user%21user.install/function/user_update_7002/7
|
||||
if ($this->getDatabase()->schema()->fieldExists('users', 'timezone_id')) {
|
||||
$fields['timezone_id'] = $this->t('Timezone (Event)');
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
|
||||
/**
|
||||
* Drupal 6 user picture source from database.
|
||||
*
|
||||
* @todo Support default picture?
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_user_picture"
|
||||
* )
|
||||
*/
|
||||
class UserPicture extends DrupalSqlBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
$query = $this->select('users', 'u')
|
||||
->condition('picture', '', '<>')
|
||||
->fields('u', array('uid', 'access', 'picture'))
|
||||
->orderBy('u.access');
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return array(
|
||||
'uid' => 'Primary Key: Unique user ID.',
|
||||
'access' => 'Timestamp for previous time user accessed the site.',
|
||||
'picture' => "Path to the user's uploaded picture.",
|
||||
);
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['uid']['type'] = 'integer';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* Drupal 6 user picture source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_user_picture_file"
|
||||
* )
|
||||
*/
|
||||
class UserPictureFile extends DrupalSqlBase {
|
||||
|
||||
/**
|
||||
* The file directory path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $filePath;
|
||||
|
||||
/**
|
||||
* The temporary file path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $tempFilePath;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
$query = $this->select('users', 'u')
|
||||
->condition('u.picture', '', '<>')
|
||||
->fields('u', array('uid', 'picture'));
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function initializeIterator() {
|
||||
$site_path = isset($this->configuration['site_path']) ? $this->configuration['site_path'] : 'sites/default';
|
||||
$this->filePath = $this->variableGet('file_directory_path', $site_path . '/files') . '/';
|
||||
$this->tempFilePath = $this->variableGet('file_directory_temp', '/tmp') . '/';
|
||||
return parent::initializeIterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$row->setSourceProperty('filename', basename($row->getSourceProperty('picture')));
|
||||
$row->setSourceProperty('file_directory_path', $this->filePath);
|
||||
$row->setSourceProperty('temp_directory_path', $this->tempFilePath);
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return array(
|
||||
'picture' => "Path to the user's uploaded picture.",
|
||||
'filename' => 'The picture filename.',
|
||||
);
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['uid']['type'] = 'integer';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
}
|
||||
57
web/core/modules/user/src/Plugin/migrate/source/d7/Role.php
Normal file
57
web/core/modules/user/src/Plugin/migrate/source/d7/Role.php
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
|
||||
/**
|
||||
* Drupal 7 role source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_user_role"
|
||||
* )
|
||||
*/
|
||||
class Role extends DrupalSqlBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
return $this->select('role', 'r')->fields('r');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return array(
|
||||
'rid' => $this->t('Role ID.'),
|
||||
'name' => $this->t('The name of the user role.'),
|
||||
'weight' => $this->t('The weight of the role.'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$permissions = $this->select('role_permission', 'rp')
|
||||
->fields('rp', ['permission'])
|
||||
->condition('rid', $row->getSourceProperty('rid'))
|
||||
->execute()
|
||||
->fetchCol();
|
||||
$row->setSourceProperty('permissions', $permissions);
|
||||
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['rid']['type'] = 'integer';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
}
|
||||
119
web/core/modules/user/src/Plugin/migrate/source/d7/User.php
Normal file
119
web/core/modules/user/src/Plugin/migrate/source/d7/User.php
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
|
||||
|
||||
/**
|
||||
* Drupal 7 user source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_user"
|
||||
* )
|
||||
*/
|
||||
class User extends FieldableEntity {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
return $this->select('users', 'u')
|
||||
->fields('u')
|
||||
->condition('u.uid', 0, '>');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
$fields = array(
|
||||
'uid' => $this->t('User ID'),
|
||||
'name' => $this->t('Username'),
|
||||
'pass' => $this->t('Password'),
|
||||
'mail' => $this->t('Email address'),
|
||||
'signature' => $this->t('Signature'),
|
||||
'signature_format' => $this->t('Signature format'),
|
||||
'created' => $this->t('Registered timestamp'),
|
||||
'access' => $this->t('Last access timestamp'),
|
||||
'login' => $this->t('Last login timestamp'),
|
||||
'status' => $this->t('Status'),
|
||||
'timezone' => $this->t('Timezone'),
|
||||
'language' => $this->t('Language'),
|
||||
'picture' => $this->t('Picture'),
|
||||
'init' => $this->t('Init'),
|
||||
'data' => $this->t('User data'),
|
||||
'roles' => $this->t('Roles'),
|
||||
);
|
||||
|
||||
// Profile fields.
|
||||
if ($this->moduleExists('profile')) {
|
||||
$fields += $this->select('profile_fields', 'pf')
|
||||
->fields('pf', array('name', 'title'))
|
||||
->execute()
|
||||
->fetchAllKeyed();
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$roles = $this->select('users_roles', 'ur')
|
||||
->fields('ur', ['rid'])
|
||||
->condition('ur.uid', $row->getSourceProperty('uid'))
|
||||
->execute()
|
||||
->fetchCol();
|
||||
$row->setSourceProperty('roles', $roles);
|
||||
|
||||
$row->setSourceProperty('data', unserialize($row->getSourceProperty('data')));
|
||||
|
||||
// Get Field API field values.
|
||||
foreach (array_keys($this->getFields('user')) as $field) {
|
||||
$row->setSourceProperty($field, $this->getFieldValues('user', $field, $row->getSourceProperty('uid')));
|
||||
}
|
||||
|
||||
// Get profile field values. This code is lifted directly from the D6
|
||||
// ProfileFieldValues plugin.
|
||||
if ($this->getDatabase()->schema()->tableExists('profile_value')) {
|
||||
$query = $this->select('profile_value', 'pv')
|
||||
->fields('pv', array('fid', 'value'));
|
||||
$query->leftJoin('profile_field', 'pf', 'pf.fid=pv.fid');
|
||||
$query->fields('pf', array('name', 'type'));
|
||||
$query->condition('uid', $row->getSourceProperty('uid'));
|
||||
$results = $query->execute();
|
||||
|
||||
foreach ($results as $profile_value) {
|
||||
if ($profile_value['type'] == 'date') {
|
||||
$date = unserialize($profile_value['value']);
|
||||
$date = date('Y-m-d', mktime(0, 0, 0, $date['month'], $date['day'], $date['year']));
|
||||
$row->setSourceProperty($profile_value['name'], array('value' => $date));
|
||||
}
|
||||
elseif ($profile_value['type'] == 'list') {
|
||||
// Explode by newline and comma.
|
||||
$row->setSourceProperty($profile_value['name'], preg_split("/[\r\n,]+/", $profile_value['value']));
|
||||
}
|
||||
else {
|
||||
$row->setSourceProperty($profile_value['name'], array($profile_value['value']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
return array(
|
||||
'uid' => array(
|
||||
'type' => 'integer',
|
||||
'alias' => 'u',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
152
web/core/modules/user/src/Plugin/views/access/Permission.php
Normal file
152
web/core/modules/user/src/Plugin/views/access/Permission.php
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\access;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Cache\CacheableDependencyInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\user\PermissionHandlerInterface;
|
||||
use Drupal\views\Plugin\views\access\AccessPluginBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\Routing\Route;
|
||||
|
||||
/**
|
||||
* Access plugin that provides permission-based access control.
|
||||
*
|
||||
* @ingroup views_access_plugins
|
||||
*
|
||||
* @ViewsAccess(
|
||||
* id = "perm",
|
||||
* title = @Translation("Permission"),
|
||||
* help = @Translation("Access will be granted to users with the specified permission string.")
|
||||
* )
|
||||
*/
|
||||
class Permission extends AccessPluginBase implements CacheableDependencyInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $usesOptions = TRUE;
|
||||
|
||||
/**
|
||||
* The permission handler.
|
||||
*
|
||||
* @var \Drupal\user\PermissionHandlerInterface
|
||||
*/
|
||||
protected $permissionHandler;
|
||||
|
||||
/**
|
||||
* The module handler.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* Constructs a Permission object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\user\PermissionHandlerInterface $permission_handler
|
||||
* The permission handler.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, PermissionHandlerInterface $permission_handler, ModuleHandlerInterface $module_handler) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->permissionHandler = $permission_handler;
|
||||
$this->moduleHandler = $module_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('user.permissions'),
|
||||
$container->get('module_handler')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access(AccountInterface $account) {
|
||||
return $account->hasPermission($this->options['perm']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function alterRouteDefinition(Route $route) {
|
||||
$route->setRequirement('_permission', $this->options['perm']);
|
||||
}
|
||||
|
||||
public function summaryTitle() {
|
||||
$permissions = $this->permissionHandler->getPermissions();
|
||||
if (isset($permissions[$this->options['perm']])) {
|
||||
return $permissions[$this->options['perm']]['title'];
|
||||
}
|
||||
|
||||
return $this->t($this->options['perm']);
|
||||
}
|
||||
|
||||
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
$options['perm'] = array('default' => 'access content');
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
|
||||
parent::buildOptionsForm($form, $form_state);
|
||||
// Get list of permissions
|
||||
$perms = [];
|
||||
$permissions = $this->permissionHandler->getPermissions();
|
||||
foreach ($permissions as $perm => $perm_item) {
|
||||
$provider = $perm_item['provider'];
|
||||
$display_name = $this->moduleHandler->getName($provider);
|
||||
$perms[$display_name][$perm] = strip_tags($perm_item['title']);
|
||||
}
|
||||
|
||||
$form['perm'] = array(
|
||||
'#type' => 'select',
|
||||
'#options' => $perms,
|
||||
'#title' => $this->t('Permission'),
|
||||
'#default_value' => $this->options['perm'],
|
||||
'#description' => $this->t('Only users with the selected permission flag will be able to access this display.'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheMaxAge() {
|
||||
return Cache::PERMANENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheContexts() {
|
||||
return ['user.permissions'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheTags() {
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
165
web/core/modules/user/src/Plugin/views/access/Role.php
Normal file
165
web/core/modules/user/src/Plugin/views/access/Role.php
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\access;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Cache\CacheableDependencyInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\user\RoleStorageInterface;
|
||||
use Drupal\views\Plugin\views\access\AccessPluginBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
* Access plugin that provides role-based access control.
|
||||
*
|
||||
* @ingroup views_access_plugins
|
||||
*
|
||||
* @ViewsAccess(
|
||||
* id = "role",
|
||||
* title = @Translation("Role"),
|
||||
* help = @Translation("Access will be granted to users with any of the specified roles.")
|
||||
* )
|
||||
*/
|
||||
class Role extends AccessPluginBase implements CacheableDependencyInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $usesOptions = TRUE;
|
||||
|
||||
/**
|
||||
* The role storage.
|
||||
*
|
||||
* @var \Drupal\user\RoleStorageInterface
|
||||
*/
|
||||
protected $roleStorage;
|
||||
|
||||
/**
|
||||
* Constructs a Role object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\user\RoleStorageInterface $role_storage
|
||||
* The role storage.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, RoleStorageInterface $role_storage) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->roleStorage = $role_storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('entity.manager')->getStorage('user_role')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access(AccountInterface $account) {
|
||||
return array_intersect(array_filter($this->options['role']), $account->getRoles());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function alterRouteDefinition(Route $route) {
|
||||
if ($this->options['role']) {
|
||||
$route->setRequirement('_role', (string) implode('+', $this->options['role']));
|
||||
}
|
||||
}
|
||||
|
||||
public function summaryTitle() {
|
||||
$count = count($this->options['role']);
|
||||
if ($count < 1) {
|
||||
return $this->t('No role(s) selected');
|
||||
}
|
||||
elseif ($count > 1) {
|
||||
return $this->t('Multiple roles');
|
||||
}
|
||||
else {
|
||||
$rids = user_role_names();
|
||||
$rid = reset($this->options['role']);
|
||||
return $rids[$rid];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
$options['role'] = array('default' => array());
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
|
||||
parent::buildOptionsForm($form, $form_state);
|
||||
$form['role'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => $this->t('Role'),
|
||||
'#default_value' => $this->options['role'],
|
||||
'#options' => array_map('\Drupal\Component\Utility\Html::escape', user_role_names()),
|
||||
'#description' => $this->t('Only the checked roles will be able to access this display.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function validateOptionsForm(&$form, FormStateInterface $form_state) {
|
||||
$role = $form_state->getValue(array('access_options', 'role'));
|
||||
$role = array_filter($role);
|
||||
|
||||
if (!$role) {
|
||||
$form_state->setError($form['role'], $this->t('You must select at least one role if type is "by role"'));
|
||||
}
|
||||
|
||||
$form_state->setValue(array('access_options', 'role'), $role);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function calculateDependencies() {
|
||||
$dependencies = parent::calculateDependencies();
|
||||
|
||||
foreach (array_keys($this->options['role']) as $rid) {
|
||||
if ($role = $this->roleStorage->load($rid)) {
|
||||
$dependencies[$role->getConfigDependencyKey()][] = $role->getConfigDependencyName();
|
||||
}
|
||||
}
|
||||
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheMaxAge() {
|
||||
return Cache::PERMANENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheContexts() {
|
||||
return ['user.roles'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheTags() {
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
62
web/core/modules/user/src/Plugin/views/argument/RolesRid.php
Normal file
62
web/core/modules/user/src/Plugin/views/argument/RolesRid.php
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\argument;
|
||||
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\views\Plugin\views\argument\ManyToOne;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Allow role ID(s) as argument.
|
||||
*
|
||||
* @ingroup views_argument_handlers
|
||||
*
|
||||
* @ViewsArgument("user__roles_rid")
|
||||
*/
|
||||
class RolesRid extends ManyToOne {
|
||||
|
||||
/**
|
||||
* The role entity storage
|
||||
*
|
||||
* @var \Drupal\user\RoleStorage
|
||||
*/
|
||||
protected $roleStorage;
|
||||
|
||||
/**
|
||||
* Constructs a \Drupal\user\Plugin\views\argument\RolesRid object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->roleStorage = $entity_manager->getStorage('user_role');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static($configuration, $plugin_id, $plugin_definition, $container->get('entity.manager'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function titleQuery() {
|
||||
$entities = $this->roleStorage->loadMultiple($this->value);
|
||||
$titles = array();
|
||||
foreach ($entities as $entity) {
|
||||
$titles[] = $entity->label();
|
||||
}
|
||||
return $titles;
|
||||
}
|
||||
|
||||
}
|
||||
62
web/core/modules/user/src/Plugin/views/argument/Uid.php
Normal file
62
web/core/modules/user/src/Plugin/views/argument/Uid.php
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\argument;
|
||||
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\views\Plugin\views\argument\NumericArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Argument handler to accept a user id.
|
||||
*
|
||||
* @ingroup views_argument_handlers
|
||||
*
|
||||
* @ViewsArgument("user_uid")
|
||||
*/
|
||||
class Uid extends NumericArgument {
|
||||
|
||||
/**
|
||||
* The user storage.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityStorageInterface
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
|
||||
* The user storage.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityStorageInterface $storage) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->storage = $storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static($configuration, $plugin_id, $plugin_definition,
|
||||
$container->get('entity.manager')->getStorage('user'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the behavior of title(). Get the name of the user.
|
||||
*
|
||||
* @return array
|
||||
* A list of usernames.
|
||||
*/
|
||||
public function titleQuery() {
|
||||
return array_map(function($account) {
|
||||
return $account->label();
|
||||
}, $this->storage->loadMultiple($this->value));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\argument_default;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Cache\CacheableDependencyInterface;
|
||||
use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase;
|
||||
|
||||
/**
|
||||
* Default argument plugin to extract the current user
|
||||
*
|
||||
* This plugin actually has no options so it does not need to do a great deal.
|
||||
*
|
||||
* @ViewsArgumentDefault(
|
||||
* id = "current_user",
|
||||
* title = @Translation("User ID from logged in user")
|
||||
* )
|
||||
*/
|
||||
class CurrentUser extends ArgumentDefaultPluginBase implements CacheableDependencyInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getArgument() {
|
||||
return \Drupal::currentUser()->id();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheMaxAge() {
|
||||
return Cache::PERMANENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheContexts() {
|
||||
return ['user'];
|
||||
}
|
||||
|
||||
}
|
||||
117
web/core/modules/user/src/Plugin/views/argument_default/User.php
Normal file
117
web/core/modules/user/src/Plugin/views/argument_default/User.php
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\argument_default;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Cache\CacheableDependencyInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\user\UserInterface;
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
/**
|
||||
* Default argument plugin to extract a user from request.
|
||||
*
|
||||
* @ViewsArgumentDefault(
|
||||
* id = "user",
|
||||
* title = @Translation("User ID from route context")
|
||||
* )
|
||||
*/
|
||||
class User extends ArgumentDefaultPluginBase implements CacheableDependencyInterface {
|
||||
|
||||
/**
|
||||
* The route match.
|
||||
*
|
||||
* @var \Drupal\Core\Routing\RouteMatchInterface
|
||||
*/
|
||||
protected $routeMatch;
|
||||
|
||||
/**
|
||||
* Constructs a new User instance.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
*
|
||||
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
|
||||
* The route match.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteMatchInterface $route_match) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->routeMatch = $route_match;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('current_route_match')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
$options['user'] = array('default' => '');
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
|
||||
$form['user'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Also look for a node and use the node author'),
|
||||
'#default_value' => $this->options['user'],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getArgument() {
|
||||
|
||||
// If there is a user object in the current route.
|
||||
if ($user = $this->routeMatch->getParameter('user')) {
|
||||
if ($user instanceof UserInterface) {
|
||||
return $user->id();
|
||||
}
|
||||
}
|
||||
|
||||
// If option to use node author; and node in current route.
|
||||
if (!empty($this->options['user']) && $node = $this->routeMatch->getParameter('node')) {
|
||||
if ($node instanceof NodeInterface) {
|
||||
return $node->getOwnerId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheMaxAge() {
|
||||
return Cache::PERMANENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheContexts() {
|
||||
return ['url'];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\argument_validator;
|
||||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\views\Plugin\views\argument\ArgumentPluginBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\views\Plugin\views\argument_validator\Entity;
|
||||
|
||||
/**
|
||||
* Validate whether an argument is a valid user.
|
||||
*
|
||||
* This supports either numeric arguments (UID) or strings (username) and
|
||||
* converts either one into the user's UID. This validator also sets the
|
||||
* argument's title to the username.
|
||||
*/
|
||||
class User extends Entity {
|
||||
|
||||
/**
|
||||
* The user storage.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityStorageInterface
|
||||
*/
|
||||
protected $userStorage;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_manager);
|
||||
|
||||
$this->userStorage = $entity_manager->getStorage('user');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
$options['restrict_roles'] = array('default' => FALSE);
|
||||
$options['roles'] = array('default' => array());
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
|
||||
parent::buildOptionsForm($form, $form_state);
|
||||
$sanitized_id = ArgumentPluginBase::encodeValidatorId($this->definition['id']);
|
||||
|
||||
$form['restrict_roles'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Restrict user based on role'),
|
||||
'#default_value' => $this->options['restrict_roles'],
|
||||
);
|
||||
|
||||
$form['roles'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => $this->t('Restrict to the selected roles'),
|
||||
'#options' => array_map(array('\Drupal\Component\Utility\Html', 'escape'), user_role_names(TRUE)),
|
||||
'#default_value' => $this->options['roles'],
|
||||
'#description' => $this->t('If no roles are selected, users from any role will be allowed.'),
|
||||
'#states' => array(
|
||||
'visible' => array(
|
||||
':input[name="options[validate][options][' . $sanitized_id . '][restrict_roles]"]' => array('checked' => TRUE),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitOptionsForm(&$form, FormStateInterface $form_state, &$options = array()) {
|
||||
// filter trash out of the options so we don't store giant unnecessary arrays
|
||||
$options['roles'] = array_filter($options['roles']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function validateEntity(EntityInterface $entity) {
|
||||
/** @var \Drupal\user\UserInterface $entity */
|
||||
$role_check_success = TRUE;
|
||||
// See if we're filtering users based on roles.
|
||||
if (!empty($this->options['restrict_roles']) && !empty($this->options['roles'])) {
|
||||
$roles = $this->options['roles'];
|
||||
if (!(bool) array_intersect($entity->getRoles(), $roles)) {
|
||||
$role_check_success = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return $role_check_success && parent::validateEntity($entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function calculateDependencies() {
|
||||
$dependencies = parent::calculateDependencies();
|
||||
|
||||
foreach ($this->entityManager->getStorage('user_role')->loadMultiple(array_keys($this->options['roles'])) as $role) {
|
||||
$dependencies[$role->getConfigDependencyKey()][] = $role->getConfigDependencyName();
|
||||
}
|
||||
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\argument_validator;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Validates whether a user name is valid.
|
||||
*
|
||||
* @ViewsArgumentValidator(
|
||||
* id = "user_name",
|
||||
* title = @Translation("User name"),
|
||||
* entity_type = "user"
|
||||
* )
|
||||
*/
|
||||
class UserName extends User {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
|
||||
parent::buildOptionsForm($form, $form_state);
|
||||
|
||||
$entity_type = $this->entityManager->getDefinition('user');
|
||||
|
||||
$form['multiple']['#options'] = array(
|
||||
0 => $this->t('Single name', array('%type' => $entity_type->getLabel())),
|
||||
1 => $this->t('One or more names separated by , or +', array('%type' => $entity_type->getLabel())),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateArgument($argument) {
|
||||
if ($this->multipleCapable && $this->options['multiple']) {
|
||||
// At this point only interested in individual IDs no matter what type,
|
||||
// just splitting by the allowed delimiters.
|
||||
$names = array_filter(preg_split('/[,+ ]/', $argument));
|
||||
}
|
||||
elseif ($argument) {
|
||||
$names = array($argument);
|
||||
}
|
||||
// No specified argument should be invalid.
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$accounts = $this->userStorage->loadByProperties(array('name' => $names));
|
||||
|
||||
// If there are no accounts, return FALSE now. As we will not enter the
|
||||
// loop below otherwise.
|
||||
if (empty($accounts)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Validate each account. If any fails break out and return false.
|
||||
foreach ($accounts as $account) {
|
||||
if (!in_array($account->getUserName(), $names) || !$this->validateEntity($account)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function processSummaryArguments(&$args) {
|
||||
// If the validation says the input is an username, we should reverse the
|
||||
// argument so it works for example for generation summary urls.
|
||||
$uids_arg_keys = array_flip($args);
|
||||
|
||||
foreach ($this->userStorage->loadMultiple($args) as $uid => $account) {
|
||||
$args[$uids_arg_keys[$uid]] = $account->label();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
115
web/core/modules/user/src/Plugin/views/field/Permissions.php
Normal file
115
web/core/modules/user/src/Plugin/views/field/Permissions.php
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\field;
|
||||
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\views\Plugin\views\field\PrerenderList;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Field handler to provide a list of permissions.
|
||||
*
|
||||
* @ingroup views_field_handlers
|
||||
*
|
||||
* @ViewsField("user_permissions")
|
||||
*/
|
||||
class Permissions extends PrerenderList {
|
||||
|
||||
/**
|
||||
* The role storage.
|
||||
*
|
||||
* @var \Drupal\user\RoleStorageInterface
|
||||
*/
|
||||
protected $roleStorage;
|
||||
|
||||
/**
|
||||
* The module handler.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, ModuleHandlerInterface $module_handler, EntityManagerInterface $entity_manager) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->roleStorage = $entity_manager->getStorage('user_role');
|
||||
$this->moduleHandler = $module_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static($configuration, $plugin_id, $plugin_definition, $container->get('module_handler'), $container->get('entity.manager'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
|
||||
parent::init($view, $display, $options);
|
||||
|
||||
$this->additional_fields['uid'] = array('table' => 'users_field_data', 'field' => 'uid');
|
||||
}
|
||||
|
||||
public function query() {
|
||||
$this->addAdditionalFields();
|
||||
$this->field_alias = $this->aliases['uid'];
|
||||
}
|
||||
|
||||
public function preRender(&$values) {
|
||||
$uids = array();
|
||||
$this->items = array();
|
||||
|
||||
$permission_names = \Drupal::service('user.permissions')->getPermissions();
|
||||
|
||||
$rids = array();
|
||||
foreach ($values as $result) {
|
||||
$user_rids = $this->getEntity($result)->getRoles();
|
||||
$uid = $this->getValue($result);
|
||||
|
||||
foreach ($user_rids as $rid) {
|
||||
$rids[$rid][] = $uid;
|
||||
}
|
||||
}
|
||||
|
||||
if ($rids) {
|
||||
$roles = $this->roleStorage->loadMultiple(array_keys($rids));
|
||||
foreach ($rids as $rid => $role_uids) {
|
||||
foreach ($roles[$rid]->getPermissions() as $permission) {
|
||||
foreach ($role_uids as $uid) {
|
||||
$this->items[$uid][$permission]['permission'] = $permission_names[$permission]['title'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($uids as $uid) {
|
||||
if (isset($this->items[$uid])) {
|
||||
ksort($this->items[$uid]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function render_item($count, $item) {
|
||||
return $item['permission'];
|
||||
}
|
||||
|
||||
}
|
||||
109
web/core/modules/user/src/Plugin/views/field/Roles.php
Normal file
109
web/core/modules/user/src/Plugin/views/field/Roles.php
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\field;
|
||||
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\views\Plugin\views\field\PrerenderList;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Field handler to provide a list of roles.
|
||||
*
|
||||
* @ingroup views_field_handlers
|
||||
*
|
||||
* @ViewsField("user_roles")
|
||||
*/
|
||||
class Roles extends PrerenderList {
|
||||
|
||||
/**
|
||||
* Database Service Object.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected $database;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Database\Connection $database
|
||||
* Database Service Object.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, Connection $database) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->database = $database;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static($configuration, $plugin_id, $plugin_definition, $container->get('database'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
|
||||
parent::init($view, $display, $options);
|
||||
|
||||
$this->additional_fields['uid'] = array('table' => 'users_field_data', 'field' => 'uid');
|
||||
}
|
||||
|
||||
public function query() {
|
||||
$this->addAdditionalFields();
|
||||
$this->field_alias = $this->aliases['uid'];
|
||||
}
|
||||
|
||||
public function preRender(&$values) {
|
||||
$uids = array();
|
||||
$this->items = array();
|
||||
|
||||
foreach ($values as $result) {
|
||||
$uids[] = $this->getValue($result);
|
||||
}
|
||||
|
||||
if ($uids) {
|
||||
$roles = user_roles();
|
||||
$result = $this->database->query('SELECT u.entity_id as uid, u.roles_target_id as rid FROM {user__roles} u WHERE u.entity_id IN ( :uids[] ) AND u.roles_target_id IN ( :rids[] )', array(':uids[]' => $uids, ':rids[]' => array_keys($roles)));
|
||||
foreach ($result as $role) {
|
||||
$this->items[$role->uid][$role->rid]['role'] = $roles[$role->rid]->label();
|
||||
$this->items[$role->uid][$role->rid]['rid'] = $role->rid;
|
||||
}
|
||||
// Sort the roles for each user by role weight.
|
||||
$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);
|
||||
// Merge with the unsorted array of role information which has the
|
||||
// effect of sorting it.
|
||||
$user_roles = array_merge($sorted_keys, $user_roles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function render_item($count, $item) {
|
||||
return $item['role'];
|
||||
}
|
||||
|
||||
protected function documentSelfTokens(&$tokens) {
|
||||
$tokens['{{ ' . $this->options['id'] . '__role' . ' }}'] = $this->t('The name of the role.');
|
||||
$tokens['{{ ' . $this->options['id'] . '__rid' . ' }}'] = $this->t('The role machine-name of the role.');
|
||||
}
|
||||
|
||||
protected function addSelfTokens(&$tokens, $item) {
|
||||
if (!empty($item['role'])) {
|
||||
$tokens['{{ ' . $this->options['id'] . '__role' . ' }}'] = $item['role'];
|
||||
$tokens['{{ ' . $this->options['id'] . '__rid' . ' }}'] = $item['rid'];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\field;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\system\Plugin\views\field\BulkForm;
|
||||
use Drupal\user\UserInterface;
|
||||
|
||||
/**
|
||||
* Defines a user operations bulk form element.
|
||||
*
|
||||
* @ViewsField("user_bulk_form")
|
||||
*/
|
||||
class UserBulkForm extends BulkForm {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Provide a more useful title to improve the accessibility.
|
||||
*/
|
||||
public function viewsForm(&$form, FormStateInterface $form_state) {
|
||||
parent::viewsForm($form, $form_state);
|
||||
|
||||
if (!empty($this->view->result)) {
|
||||
foreach ($this->view->result as $row_index => $result) {
|
||||
$account = $result->_entity;
|
||||
if ($account instanceof UserInterface) {
|
||||
$form[$this->options['id']][$row_index]['#title'] = $this->t('Update the user %name', array('%name' => $account->label()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function emptySelectedMessage() {
|
||||
return $this->t('No users selected.');
|
||||
}
|
||||
|
||||
}
|
||||
108
web/core/modules/user/src/Plugin/views/field/UserData.php
Normal file
108
web/core/modules/user/src/Plugin/views/field/UserData.php
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\field;
|
||||
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\views\Plugin\views\field\FieldPluginBase;
|
||||
use Drupal\views\ResultRow;
|
||||
use Drupal\user\UserDataInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides access to the user data service.
|
||||
*
|
||||
* @ingroup views_field_handlers
|
||||
*
|
||||
* @see \Drupal\user\UserDataInterface
|
||||
*
|
||||
* @ViewsField("user_data")
|
||||
*/
|
||||
class UserData extends FieldPluginBase {
|
||||
|
||||
/**
|
||||
* Provides the user data service object.
|
||||
*
|
||||
* @var \Drupal\user\UserDataInterface
|
||||
*/
|
||||
protected $userData;
|
||||
|
||||
/**
|
||||
* The module handler.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static($configuration, $plugin_id, $plugin_definition, $container->get('user.data'), $container->get('module_handler'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a UserData object.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, UserDataInterface $user_data, ModuleHandlerInterface $module_handler) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->userData = $user_data;
|
||||
$this->moduleHandler = $module_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
|
||||
$options['data_module'] = array('default' => '');
|
||||
$options['data_name'] = array('default' => '');
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
|
||||
parent::buildOptionsForm($form, $form_state);
|
||||
|
||||
$modules = $this->moduleHandler->getModuleList();
|
||||
$names = array();
|
||||
foreach (array_keys($modules) as $name) {
|
||||
$names[$name] = $this->moduleHandler->getName($name);
|
||||
}
|
||||
|
||||
$form['data_module'] = array(
|
||||
'#title' => $this->t('Module name'),
|
||||
'#type' => 'select',
|
||||
'#description' => $this->t('The module which sets this user data.'),
|
||||
'#default_value' => $this->options['data_module'],
|
||||
'#options' => $names,
|
||||
);
|
||||
|
||||
$form['data_name'] = array(
|
||||
'#title' => $this->t('Name'),
|
||||
'#type' => 'textfield',
|
||||
'#description' => $this->t('The name of the data key.'),
|
||||
'#default_value' => $this->options['data_name'],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function render(ResultRow $values) {
|
||||
$uid = $this->getValue($values);
|
||||
$data = $this->userData->get($this->options['data_module'], $uid, $this->options['data_name']);
|
||||
|
||||
// Don't sanitize if no value was found.
|
||||
if (isset($data)) {
|
||||
return $this->sanitizeValue($data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
57
web/core/modules/user/src/Plugin/views/filter/Current.php
Normal file
57
web/core/modules/user/src/Plugin/views/filter/Current.php
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\filter;
|
||||
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\views\Plugin\views\filter\BooleanOperator;
|
||||
|
||||
/**
|
||||
* Filter handler for the current user.
|
||||
*
|
||||
* @ingroup views_filter_handlers
|
||||
*
|
||||
* @ViewsFilter("user_current")
|
||||
*/
|
||||
class Current extends BooleanOperator {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
|
||||
parent::init($view, $display, $options);
|
||||
|
||||
$this->value_value = $this->t('Is the logged in user');
|
||||
}
|
||||
|
||||
public function query() {
|
||||
$this->ensureMyTable();
|
||||
|
||||
$field = $this->tableAlias . '.' . $this->realField . ' ';
|
||||
$or = db_or();
|
||||
|
||||
if (empty($this->value)) {
|
||||
$or->condition($field, '***CURRENT_USER***', '<>');
|
||||
if ($this->accept_null) {
|
||||
$or->isNull($field);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$or->condition($field, '***CURRENT_USER***', '=');
|
||||
}
|
||||
$this->query->addWhere($this->options['group'], $or);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheContexts() {
|
||||
$contexts = parent::getCacheContexts();
|
||||
|
||||
// This filter depends on the current user.
|
||||
$contexts[] = 'user';
|
||||
|
||||
return $contexts;
|
||||
}
|
||||
|
||||
}
|
||||
126
web/core/modules/user/src/Plugin/views/filter/Name.php
Normal file
126
web/core/modules/user/src/Plugin/views/filter/Name.php
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\filter;
|
||||
|
||||
use Drupal\Core\Entity\Element\EntityAutocomplete;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\user\Entity\User;
|
||||
use Drupal\views\Plugin\views\filter\InOperator;
|
||||
|
||||
/**
|
||||
* Filter handler for usernames.
|
||||
*
|
||||
* @ingroup views_filter_handlers
|
||||
*
|
||||
* @ViewsFilter("user_name")
|
||||
*/
|
||||
class Name extends InOperator {
|
||||
|
||||
protected $alwaysMultiple = TRUE;
|
||||
|
||||
protected function valueForm(&$form, FormStateInterface $form_state) {
|
||||
$users = $this->value ? User::loadMultiple($this->value) : array();
|
||||
$default_value = EntityAutocomplete::getEntityLabels($users);
|
||||
$form['value'] = array(
|
||||
'#type' => 'entity_autocomplete',
|
||||
'#title' => $this->t('Usernames'),
|
||||
'#description' => $this->t('Enter a comma separated list of user names.'),
|
||||
'#target_type' => 'user',
|
||||
'#tags' => TRUE,
|
||||
'#default_value' => $default_value,
|
||||
'#process_default_value' => $this->isExposed(),
|
||||
);
|
||||
|
||||
$user_input = $form_state->getUserInput();
|
||||
if ($form_state->get('exposed') && !isset($user_input[$this->options['expose']['identifier']])) {
|
||||
$user_input[$this->options['expose']['identifier']] = $default_value;
|
||||
$form_state->setUserInput($user_input);
|
||||
}
|
||||
}
|
||||
|
||||
protected function valueValidate($form, FormStateInterface $form_state) {
|
||||
$uids = [];
|
||||
if ($values = $form_state->getValue(array('options', 'value'))) {
|
||||
foreach ($values as $value) {
|
||||
$uids[] = $value['target_id'];
|
||||
}
|
||||
sort($uids);
|
||||
}
|
||||
$form_state->setValue(array('options', 'value'), $uids);
|
||||
}
|
||||
|
||||
public function acceptExposedInput($input) {
|
||||
$rc = parent::acceptExposedInput($input);
|
||||
|
||||
if ($rc) {
|
||||
// If we have previously validated input, override.
|
||||
if (isset($this->validated_exposed_input)) {
|
||||
$this->value = $this->validated_exposed_input;
|
||||
}
|
||||
}
|
||||
|
||||
return $rc;
|
||||
}
|
||||
|
||||
public function validateExposed(&$form, FormStateInterface $form_state) {
|
||||
if (empty($this->options['exposed'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($this->options['expose']['identifier'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$identifier = $this->options['expose']['identifier'];
|
||||
$input = $form_state->getValue($identifier);
|
||||
|
||||
if ($this->options['is_grouped'] && isset($this->options['group_info']['group_items'][$input])) {
|
||||
$this->operator = $this->options['group_info']['group_items'][$input]['operator'];
|
||||
$input = $this->options['group_info']['group_items'][$input]['value'];
|
||||
}
|
||||
|
||||
$uids = [];
|
||||
$values = $form_state->getValue($identifier);
|
||||
if ($values && (!$this->options['is_grouped'] || ($this->options['is_grouped'] && ($input != 'All')))) {
|
||||
foreach ($values as $value) {
|
||||
$uids[] = $value['target_id'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($uids) {
|
||||
$this->validated_exposed_input = $uids;
|
||||
}
|
||||
}
|
||||
|
||||
protected function valueSubmit($form, FormStateInterface $form_state) {
|
||||
// prevent array filter from removing our anonymous user.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getValueOptions() {
|
||||
return $this->valueOptions;
|
||||
}
|
||||
|
||||
public function adminSummary() {
|
||||
// set up $this->valueOptions for the parent summary
|
||||
$this->valueOptions = array();
|
||||
|
||||
if ($this->value) {
|
||||
$result = \Drupal::entityTypeManager()->getStorage('user')
|
||||
->loadByProperties(['uid' => $this->value]);
|
||||
foreach ($result as $account) {
|
||||
if ($account->id()) {
|
||||
$this->valueOptions[$account->id()] = $account->label();
|
||||
}
|
||||
else {
|
||||
$this->valueOptions[$account->id()] = 'Anonymous'; // Intentionally NOT translated.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parent::adminSummary();
|
||||
}
|
||||
|
||||
}
|
||||
107
web/core/modules/user/src/Plugin/views/filter/Permissions.php
Normal file
107
web/core/modules/user/src/Plugin/views/filter/Permissions.php
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\filter;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\user\PermissionHandlerInterface;
|
||||
use Drupal\views\Plugin\views\filter\ManyToOne;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Filter handler for user roles.
|
||||
*
|
||||
* @ingroup views_filter_handlers
|
||||
*
|
||||
* @ViewsFilter("user_permissions")
|
||||
*/
|
||||
class Permissions extends ManyToOne {
|
||||
|
||||
/**
|
||||
* The permission handler.
|
||||
*
|
||||
* @var \Drupal\user\PermissionHandlerInterface
|
||||
*/
|
||||
protected $permissionHandler;
|
||||
|
||||
/**
|
||||
* The module handler.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* Constructs a Permissions object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\user\PermissionHandlerInterface $permission_handler
|
||||
* The permission handler.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, PermissionHandlerInterface $permission_handler, ModuleHandlerInterface $module_handler) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->permissionHandler = $permission_handler;
|
||||
$this->moduleHandler = $module_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('user.permissions'),
|
||||
$container->get('module_handler')
|
||||
);
|
||||
}
|
||||
|
||||
public function getValueOptions() {
|
||||
if (!isset($this->valueOptions)) {
|
||||
$permissions = $this->permissionHandler->getPermissions();
|
||||
foreach ($permissions as $perm => $perm_item) {
|
||||
$provider = $perm_item['provider'];
|
||||
$display_name = $this->moduleHandler->getName($provider);
|
||||
$this->valueOptions[$display_name][$perm] = Html::escape(strip_tags($perm_item['title']));
|
||||
}
|
||||
return $this->valueOptions;
|
||||
}
|
||||
else {
|
||||
return $this->valueOptions;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Replace the configured permission with a filter by all roles that have this
|
||||
* permission.
|
||||
*/
|
||||
public function query() {
|
||||
// @todo user_role_names() should maybe support multiple permissions.
|
||||
$rids = array();
|
||||
// Get all role IDs that have the configured permissions.
|
||||
foreach ($this->value as $permission) {
|
||||
$roles = user_role_names(FALSE, $permission);
|
||||
// user_role_names() returns an array with the role IDs as keys, so take
|
||||
// the array keys and merge them with previously found role IDs.
|
||||
$rids = array_merge($rids, array_keys($roles));
|
||||
}
|
||||
// Remove any duplicate role IDs.
|
||||
$rids = array_unique($rids);
|
||||
$this->value = $rids;
|
||||
|
||||
// $this->value contains the role IDs that have the configured permission.
|
||||
parent::query();
|
||||
}
|
||||
|
||||
}
|
||||
84
web/core/modules/user/src/Plugin/views/filter/Roles.php
Normal file
84
web/core/modules/user/src/Plugin/views/filter/Roles.php
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\filter;
|
||||
|
||||
use Drupal\user\RoleInterface;
|
||||
use Drupal\user\RoleStorageInterface;
|
||||
use Drupal\views\Plugin\views\filter\ManyToOne;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Filter handler for user roles.
|
||||
*
|
||||
* @ingroup views_filter_handlers
|
||||
*
|
||||
* @ViewsFilter("user_roles")
|
||||
*/
|
||||
class Roles extends ManyToOne {
|
||||
|
||||
/**
|
||||
* The role storage.
|
||||
*
|
||||
* @var \Drupal\user\RoleStorageInterface
|
||||
*/
|
||||
protected $roleStorage;
|
||||
|
||||
/**
|
||||
* Constructs a Roles object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\user\RoleStorageInterface $role_storage
|
||||
* The role storage.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, RoleStorageInterface $role_storage) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->roleStorage = $role_storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('entity.manager')->getStorage('user_role')
|
||||
);
|
||||
}
|
||||
|
||||
public function getValueOptions() {
|
||||
$this->valueOptions = user_role_names(TRUE);
|
||||
unset($this->valueOptions[RoleInterface::AUTHENTICATED_ID]);
|
||||
return $this->valueOptions;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Override empty and not empty operator labels to be clearer for user roles.
|
||||
*/
|
||||
function operators() {
|
||||
$operators = parent::operators();
|
||||
$operators['empty']['title'] = $this->t("Only has the 'authenticated user' role");
|
||||
$operators['not empty']['title'] = $this->t("Has roles in addition to 'authenticated user'");
|
||||
return $operators;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function calculateDependencies() {
|
||||
$dependencies = array();
|
||||
foreach ($this->value as $role_id) {
|
||||
$role = $this->roleStorage->load($role_id);
|
||||
$dependencies[$role->getConfigDependencyKey()][] = $role->getConfigDependencyName();
|
||||
}
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
}
|
||||
28
web/core/modules/user/src/Plugin/views/row/UserRow.php
Normal file
28
web/core/modules/user/src/Plugin/views/row/UserRow.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\row;
|
||||
|
||||
use Drupal\views\Plugin\views\row\EntityRow;
|
||||
|
||||
/**
|
||||
* A row plugin which renders a user.
|
||||
*
|
||||
* @ingroup views_row_plugins
|
||||
*
|
||||
* @ViewsRow(
|
||||
* id = "entity:user",
|
||||
* )
|
||||
*/
|
||||
class UserRow extends EntityRow {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
$options['view_mode']['default'] = 'full';
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
}
|
||||
76
web/core/modules/user/src/Plugin/views/wizard/Users.php
Normal file
76
web/core/modules/user/src/Plugin/views/wizard/Users.php
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\views\wizard;
|
||||
|
||||
use Drupal\views\Plugin\views\wizard\WizardPluginBase;
|
||||
|
||||
/**
|
||||
* @todo: replace numbers with constants.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tests creating user views with the wizard.
|
||||
*
|
||||
* @ViewsWizard(
|
||||
* id = "users",
|
||||
* base_table = "users_field_data",
|
||||
* title = @Translation("Users")
|
||||
* )
|
||||
*/
|
||||
class Users extends WizardPluginBase {
|
||||
|
||||
/**
|
||||
* Set the created column.
|
||||
*/
|
||||
protected $createdColumn = 'created';
|
||||
|
||||
/**
|
||||
* Set default values for the filters.
|
||||
*/
|
||||
protected $filters = array(
|
||||
'status' => array(
|
||||
'value' => TRUE,
|
||||
'table' => 'users_field_data',
|
||||
'field' => 'status',
|
||||
'plugin_id' => 'boolean',
|
||||
'entity_type' => 'user',
|
||||
'entity_field' => 'status',
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function defaultDisplayOptions() {
|
||||
$display_options = parent::defaultDisplayOptions();
|
||||
|
||||
// Add permission-based access control.
|
||||
$display_options['access']['type'] = 'perm';
|
||||
$display_options['access']['options']['perm'] = 'access user profiles';
|
||||
|
||||
// Remove the default fields, since we are customizing them here.
|
||||
unset($display_options['fields']);
|
||||
|
||||
/* Field: User: Name */
|
||||
$display_options['fields']['name']['id'] = 'name';
|
||||
$display_options['fields']['name']['table'] = 'users_field_data';
|
||||
$display_options['fields']['name']['field'] = 'name';
|
||||
$display_options['fields']['name']['entity_type'] = 'user';
|
||||
$display_options['fields']['name']['entity_field'] = 'name';
|
||||
$display_options['fields']['name']['label'] = '';
|
||||
$display_options['fields']['name']['alter']['alter_text'] = 0;
|
||||
$display_options['fields']['name']['alter']['make_link'] = 0;
|
||||
$display_options['fields']['name']['alter']['absolute'] = 0;
|
||||
$display_options['fields']['name']['alter']['trim'] = 0;
|
||||
$display_options['fields']['name']['alter']['word_boundary'] = 0;
|
||||
$display_options['fields']['name']['alter']['ellipsis'] = 0;
|
||||
$display_options['fields']['name']['alter']['strip_tags'] = 0;
|
||||
$display_options['fields']['name']['alter']['html'] = 0;
|
||||
$display_options['fields']['name']['hide_empty'] = 0;
|
||||
$display_options['fields']['name']['empty_zero'] = 0;
|
||||
$display_options['fields']['name']['plugin_id'] = 'field';
|
||||
|
||||
return $display_options;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in a new issue