Existe uma função para obter o objeto de usuário atual que evita acessar a variável global?

29

Eu sempre fui com isso global $user;. No entanto, me lembro de ter visto algo em um módulo contribuído que retornou o objeto de usuário atual sem usar o global $user.

Essa função existe no núcleo do Drupal 7 ou está usando a variável global da maneira recomendada de fato para obter o objeto de usuário atual?

Alex Weber
fonte
por que você não usaria apenas $ user global?
21412 saadlulu
5
O uso de $ global user pode criar um comportamento indesejado em potencial se for descuidado posteriormente no código.
21712 Alex Weber

Respostas:

22

A função que você poderia usar é user_uid_optional_load () ; sem argumentos, ele retorna o objeto de usuário para o usuário conectado no momento. Ele ainda usa o global $usere carrega o objeto completo do banco de dados, incluindo os campos associados aos usuários, mas evita que seu código altere acidentalmente o conteúdo da variável global $user, pois não é referenciado no seu código.

function user_uid_optional_load($uid = NULL) {
  if (!isset($uid)) {
    $uid = $GLOBALS['user']->uid;
  }
  return user_load($uid);
}

Se você não precisar do objeto completo, poderá usar o código já relatado nas outras respostas. Se quiser ter certeza de que não altera o objeto global, você pode copiar a variável global em uma variável local, como no snippet a seguir.

$account = $GLOBALS['user'];
// Use $account.

No Drupal 8, você simplesmente usa o método estático \Drupal::currentUser()para obter o equivalente ao Drupal 7 $GLOBALS['user']e \Drupal\user\Entity\User::load(\Drupal::currentUser()->id())obter um objeto totalmente carregado com todos os seus campos de API de campo. Não há mais o risco de substituir uma variável global com todas as consequências.
No caso de você precisar trocar o usuário atual com, por exemplo, o usuário anônimo, o código usado no Drupal 8 é o seguinte.

$accountSwitcher = Drupal::service('account_switcher');
$accountSwitcher->switchTo(new Drupal\Core\Session\AnonymousUserSession());

// Your code here.

// Eventually, restore the user account.
$accountSwitcher->switchBack();
kiamlaluno
fonte
20

O $userobjeto é declarado como uma variável global; portanto, se você quiser acessá-lo, precisará usar:

global $user;
$account = $user;

ou

$account = $GLOBALS['user'];

Na verdade, não parece haver uma maneira padrão de fazer isso no Drupal. Se você olhar o módulo do nó, por exemplo, a node_access_grants()função usa este código:

if (!isset($account)) {
  $account = $GLOBALS['user'];
}

Enquanto a próxima função no arquivo node_access_view_all_nodes(),, usa isto:

global $user;
if (!$account) {
  $account = $user;
}

A resposta simples é que ambos são válidos. Eu acho que o uso de $GLOBALSé para que a variável nomeada $usernão esteja ativa no escopo atual e, portanto, não possa ser substituída por uma chamada descuidada para, por exemplo, $user = NULLmais adiante na função. Eu não sou 100% nisso.

Clive
fonte
é isso que eu sei e concordo em sua última declaração.
21412 saadlulu
1
global $user;deve ser geralmente usado quando a variável é referida mais de uma vez e $GLOBALS['user']deve ser usado quando é usada apenas uma vez no código da função; O código Drupal não é constante nisso. Há um caso em que global $user;é necessário: quando o objeto de usuário é passado drupal_alter()para permitir que módulos de terceiros alterem o usuário ativo no momento (o que não é algo realmente implementado no Drupal).
kiamlaluno
1
global $usernão é a mesma coisa que user_uid_optional_load (). O primeiro é carregado da sessão e não é um objeto de usuário totalmente carregado (com campos e ganchos invocados) enquanto o segundo é. Portanto, eu não listaria isso como uma opção. O objetivo dessa função é ser usado para argumentos de menu nomeado que podem opcionalmente aceitar um ID de usuário e, por outro lado, usar como padrão o usuário atual. / user / uid é o exemplo principal.
Berdir
@Berdir Obrigado, eu não sabia que não global $userestava totalmente carregado por padrão (embora faça sentido e explique algumas coisas sobre as quais me perguntei antes). Eu tirei isso da resposta.
Clive
Obrigado Clive, suponho que usar o usuário $ global e copiá-lo para uma variável da conta $ seja provavelmente a alternativa mais segura. Eu estava realmente lookng para user_uid_optional_load () embora :)
Alex Weber
3

É tão simples quanto declarar o objeto $ user global (existente) dentro do escopo de sua função:

global $user;

Lembre-se de que as alterações feitas nesse objeto o afetam globalmente, ou seja,

global $user;
$user->uid = 1;

acabou de conceder ao usuário atual 1 privilégios. É por isso que normalmente $ user é atribuído a $ account para que os dados possam ser alterados sem afetar o usuário conectado no momento (a menos, é claro, que você queira).

Charlie Schliesser
fonte