Próximo post

Desenvolvimento Drupal like a Boss com Drush and Features

Leia mais»
ago 31 2012

Use o Entity API para lidar com nodes no Drupal

Ao trabalhar com o Drupal, é comum ter de programaticamente carregar nodes e obter os valores de seus campos. Muitas vezes também precisamos modificar um node e salvá-lo programaticamente:

1
2
3
4
$node = node_load($nid);
$nome = $node->field_nome[LANGUAGE_NONE][0]['value'];
$node->field_nome[LANGUAGE_NONE][0]['value'] = 'Ronaldo';
node_save($node);

Certo? Errado!

Bom, mais ou menos. Vamo combinar que não está errado mas que é meio porco... Por que?

Em primeiro lugar, estes LANGUAGE_NONE são bem chatos hem (pior ainda se você está colocando "und"). Isto até passa desapercebido quando somente há um idioma mas pode ter certeza que dará problemas em sites multilingues. Outra coisa chata é ter que colocar o [0] quando você sabe que só é permitido um valor.

Entity metadata wrappers

Se você não sabe o que é um wrapper, você poderá ler mais depois, mas por agora entenda que é um jeito diferente de você interagir com algum objeto ou entidade, no caso do Drupal.

Por que usar um wrapper? Por ser uma maneira de abstrair uma operação comum e fornecer uma interface única para que vários objetos diferentes consigam realizá-la. Este tipo de implementação também pode ocultar bastante da complexidade envolvida na operação e manter a API concisa e fácil.

Na prática

O módulo Entity API fornece uma API alternativa para lidar com entidades:

1
2
3
4
56
7
$node = node_load($nid);
$wrapper = entity_metadata_wrapper('node', $node);
$nome = $wrapper->field_nome->value();
$wrapper->field_nome = 'Ronaldo';
$wrapper->field_nome->set('Ronaldo'); // Síntaxe alternativa.$wrapper->field_nome[0]->set('Ronaldo'); // Mais uma alternativa.
$wrapper->save();

E aí? Bem melhor! Repare que, em casos de campos com 1 só valor, podemos omitir o [0] e acessá-lo diretamente. Mas se quiser acessar um determinado delta de um campo com vários valores, pode usar a chave normalmente.

O maior benefício é que não precisamos mais nos preocupar com nenhum idioma, pois esta parte foi abstraída. Somente temos que saber o nome do campo e o wrapper se ocupa do resto. A cereja no bolo é que isto se aplica para toda e qualquer entidade, não só nodes.

Tem mais!

Se vocês olharem a documentação da função entity_metadata_wrapper(), verão que o segundo parâmetro é opcional. Ou seja, podemos instanciar um wrapper para qualquer tipo de entidade sem necessariamente ter um objeto em mãos.

Isto pode ser muito útil para introspeção, como por exemplo descobrir quais as propriedades de um tipo de entidade.

1
2
3
4
$wrapper = entity_metadata_wrapper('user');
// Para ver todas as propriedades:
var_dump($wrapper->getPropertyInfo());
// Se você estiver usando o Devel aproveita e manda um krumo() ou dpm() aí.

Outro uso comum é criar uma nova entidade:

1
2
3
4
$node = entity_metadata_wrapper('node');
$node->type = 'fenomeno';
$node->title = 'Ronaldo';
$node->save();

OBS - Para nodes meio que tanto faz ele porque não tem uma classe propriamente dita; são apenas uma stdClass, mas pode ser útil para outros tipos de entidades, principalmente no mundo contrib, por exemplo: Profile2, , , etc.

Não teremos este problema no Drupal 8, já que as entidades do core terão classes próprias como Node ou User, mas enquanto ele não chega, podemos já ir nos acoustumando a trabalhar desta nova maneira que, além de mais elegante, é menos sujeita a erros.

[]s

Se curtiu este post, por favor tome alguns segundos para compartilhá-lo usando os links do lado esquerdo! Valeu!!!