Solución:
$user = Drupal::currentUser();
Ver el Drupal
clase. Hay muchos métodos de ayuda; la mayoría de ellos son accesos directos a los servicios, por lo que no tiene que llamar Drupal::service()
directamente.
Tenga en cuenta que el usuario actual no es la entidad de usuario, es solo el proxy de usuario. Puede obtener información básica de él, pero los campos u otra lógica específica de la entidad no están presentes. Para acceder a la entidad de usuario hay que cargarla manualmente:
$user = User::load(Drupal::currentUser()->id());
Desafortunadamente no hay método directo como Drupal::currentUser()->getEntity()
🙁
Ejemplo de como cargar usuario actual y recuperar datos de campo desde el objeto de usuario.
<?php
// Load the current user.
$user = DrupaluserEntityUser::load(Drupal::currentUser()->id());
// retrieve field data from that user
$website = $user->get('field_website')->value;
$body = $user->get('body')->value;
$email = $user->get('mail')->value;
$name = $user->get('name')->value;
$uid= $user->get('uid')->value;
?>
Accediendo a métodos en el Drupal
clase global (como ::currentUser()
) está bien en el código de procedimiento (por ejemplo, en su mymodule.module
archivo) pero en su propio código OO debe intentar acceder al @current_user
servicio, a través de un patrón estándar llamado inyección de dependencia (DI):
<?php
namespace Drupalmymodule;
use DrupalCoreSessionAccountProxyInterface;
class MyClass {
/**
* @var AccountProxy
*/
protected $currentUser;
public function __construct(AccountProxyInterface $currentUser) {
$this->currentUser = $currentUser;
}
public function doSomething() {
$currentUserId = $this->currentUser->id();
/* ... */
}
}
Este patrón permite que su código se pruebe en completo aislamiento, con un maniquí $currentUser
objeto (cualquier cosa que implemente AccountProxyInterface
y puede reducir enormemente los gastos generales de mantenimiento.
Sin embargo, DI no es muy intuitivo y lleva un tiempo comprenderlo. La forma en que ingresa el servicio en su constructor de objetos depende de lo que sea realmente el objeto en Drupal, por ejemplo, los complementos se comportan de manera diferente a los servicios registrados. Hay más información sobre DI en Drupal 8 en los documentos.
[edit] Se introdujo una edición sugerida para esta respuesta (que fue rechazada por los moderadores) public static function create()
en el código, sin más explicaciones. Sin embargo, sería engañoso agregar este método de clase sin más discusión.
Como referencia, así es como se vería la función create ():
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('current_user')
);
}
El método de clase es no utilizado por cualquier servicio que registre a través de un módulo mymodule.services.yml
: para estos, el contenedor llama directamente al constructor. Solo es útil para inyectar en clases que no son de servicio; por ejemplo:
- creando un formulario personalizado: debe declarar que implementa
ContainerInjectionInterface
para que el contenedor sepa buscar::create()
. - creando un complemento de Drupal, utilizando la arquitectura de complemento más amplia: debe declarar que implementa
ContainerFactoryPluginInterface
, que exige una firma de método diferente para::create()
.
Este no es el lugar para expandir demasiado la inyección de dependencia, pero más información sobre la ::create()
El método está disponible en esta entrada de blog.