¿Cómo encuentro los métodos públicos disponibles?

9

Estoy descubriendo que el mayor problema al trabajar con Drupal 8 es que no puedo obtener los datos que necesito. Drupal 8 quiere que use métodos públicos en lugar de perforar manualmente a través de un objeto. ¡El problema es que no puedo encontrar una manera consistente de obtener una lista de los métodos disponibles! (existen mágicamente, y siento que se supone que debo saber sobre ellos). =

Para este ejemplo, supongamos que tengo un tipo de contenido con un campo de video. Necesito obtener la URL sin procesar del archivo de video en ese campo.

Entonces comenzaría con una identificación de nodo ($ nid), y de alguna manera tengo que descubrir cómo cargar el nodo. Esto no es tan malo porque hay muchos ejemplos. Así que hago algo así $node = \Drupal\node\Entity\Node::load($nid);.

Hasta ahora tan bueno. Entonces necesito obtener el valor de mi campo de video (field_main_video). Esto me llevó SIEMPRE a descubrir porque hay documentación contradictoria en la red. Finalmente descubrí que tendría que hacer algo como esto (porque es un elemento de varios valores):

$video = \Drupal\node\Entity\Node::load($nid)->field_main_video->getValue();

... luego recorre la matriz, etc. Usar kint tampoco me ayudó a encontrar esto. Porque, por ejemplo, si yo kint($node)y miro bajo métodos, no veo getValue () como un elemento allí. Todavía no es terrible, porque había suficientes ejemplos para resolverlo.

Sin embargo, a medida que profundizo, lo que no sabía (esta es la parte importante) fue que en lugar de obtener la identificación de la entidad del campo de video, luego cargar la entidad, luego encontrar el campo "uri" en la entidad, etc. (como Lo haría en D7): ¡había un método que me permitía obtener el URI todo en esta misma línea de código!

$url = \Drupal\node\Entity\Node::load($nid)->field_main_video->entity->getFileUri();

Pero, ¿cómo podría haber sabido que existía getFileUri ()? Me topé con él en una publicación de blog. Esto realmente hace que obtener un URI sea más fácil que en D7 ... pero solo si sabes (mágicamente) qué métodos existen para cada 'nivel' de un objeto.

Al final, con este ejemplo, pregunto: ¿Cómo encuentra todos los métodos públicos para cada nivel de un objeto de una manera fácil de leer y entender? Tenga en cuenta que parece que debería haber una forma centrada en drupal (es decir, módulo de desarrollo) de hacer esto en lugar de buscar manualmente api.drupal.org o usar algo IDE específico.

Poli
fuente
1
La documentación oficial está en api.drupal.org. Una vez que comprende la clase del objeto que maneja, obtiene todos los métodos, incluidos los heredados.
kiamlaluno
1
... pero en lugar de buscar todo en api.drupal.org, ¿seguramente hay una manera en php / devel para volcar los métodos disponibles en la pantalla con el comando?
Bobby

Respuestas:

14

Las entidades de contenido son diferentes de la mayoría de las otras cosas en que a menudo no tienen métodos e interfaces adecuadas, al menos no para campos configurables.

En el caso de entidades y campos de contenido, los métodos públicos no son realmente lo que realmente quiere saber, lo que quiere saber es sobre campos y propiedades. Y solo cuando llegas a una entidad nuevamente a través de una referencia, entonces los métodos son importantes.

Para una descripción general, siempre me refiero a la gran hoja de trucos de API de Entity .

Las entidades de contenido tienen una estructura fija, Entidad> Campo (FieldItemList)> FieldItem -> Propiedad. Una propiedad es escalar o una referencia a otra cosa, por ejemplo, otra entidad, un objeto de lenguaje, un objeto de fecha, ...

Para algunos ejemplos específicos, algunos fragmentos útiles:

// List of fields that an entity has, the field definitions also have a lot of information like the type.
array_keys($entity->getFieldDefinitions())

// Use get() instead of the magic __get() on the entity level then you at least get some type hints.
$entity->get('field_name').

// Get the list of properties a certain field has, use array_keys() again for just the names, but the definitions also have the type and if it's computed or not.
$entity->getFieldDefinition('field_name')->getFieldStorageDefinition()->getPropertyDefinitions()

// Most field types have value property, but e.g. entity references have target_id and the computed entity. as you found. File and Image fields have additional properties like title/alt/description.
$entity->get('field_name')->value
$entity->get('field_name')->target_id
$entity->get('field_name')->entity

// Note that get('value') is not the same as ->value on the field item level, get() returns a typed data object, get('value')->getValue() is the same as ->value.

// When not specified, the delta 0 is assumed (all fields are a list internally, even something like the node id), you can use array access or the delta to access another delta, make sure it exists.
$entity->get('field_name')[1]->value
$entity->get('field_name')->get(1)->value

// When you have an entity reference, you can get the entity type and class like this:
$entity->get('field_name')->entity->getEntityTypeId()
$entity->get('field_name')->entity->getEntityType()->getClass()
// or 
get_class($entity->get('field_name')->entity)

// From there you can look up the interface and type hint against that, to a) make sure you have a valid, loadable reference and get type hints in an IDE:
$file = $entity->get('field_name')->entity;
if ($file instanceof \Drupal\file\FileInterface) {
  $file->getFileUri();
}
Berdir
fuente
¡Agradable! Esto va a tomar un poco de tiempo para digerir, pero me estoy inclinando a que esta sea la respuesta aceptada. ¡Gracias! No responde exactamente la pregunta, pero eso es solo porque mi pregunta y mi ejemplo eran como dos preguntas diferentes. ¡Gracias!
Bobby
1
@ Berdir, esta es una lista impresionante de ejemplos, realmente acertados. Solo buscaba información en google, cualquier información y nada cerca de esto. Gran respuesta, material de libro.
Marko Blazekovic el
4

No estoy seguro de si eso responderá completamente a su pregunta, pero lo que me ayuda mucho es usar la función de diagramas en PhpStorm.

Por ejemplo, mostrando la jerarquía ingrese la descripción de la imagen aquí

Tiene opciones para mostrar también los nombres de los métodos.

ingrese la descripción de la imagen aquí

Espero que esto te ayude de alguna manera.

Oleg Videnov
fuente
También puede abrir una clase con comando + clic, luego comando + 7 o hacer clic en la pestaña Estructura para ver la estructura de la clase (donde estaría la vista del directorio del proyecto) para escanear rápidamente la misma información sin abrir UML.
Kevin
No uso phpstorm, pero es bueno saberlo para futuras referencias. Estoy buscando una manera de hacer esto usando devel o algo centrado en drupal. seguramente algo debe construirse en alguna parte?
Bobby
Lamento decir eso, pero realmente no creo que en este momento pueda jugar de manera eficiente con la API sin usar este IDE.
Oleg Videnov
NetBeans también incluye algunos diagramas de jerarquía PHP. Probablemente no sea tan genial, pero NetBeans es software libre (PHP Storm es de código cerrado y en mi humilde opinión es caro) y puedes descargarlo gratis.
sanzante
Cualquier IDE que valga la pena puede hacer esto. BTW PHPStorm no es costoso si utiliza lo que tiene para ofrecer. Puede usar la versión gratuita de EAP, y si trabaja en un proyecto de código abierto (módulos o temas de Drupal), JetBrains le dará una licencia gratuita. No es una discusión por aquí sin embargo.
Kevin
4

Bueno, me encontré usando con bastante frecuencia la combinación de var_dump(get_class_methods($object))tener una lista de métodos disponibles para la clase dada.

También busco a menudo api.drupal.orgmás detalles.

yvan
fuente
2
Esta parece ser la respuesta más relacionada con lo que estaba buscando hasta ahora. ¡Gracias!
Bobby
0

Ya estás muy cerca.

Primero, veamos la definición del método: https://api.drupal.org/api/drupal/core%21modules%21file%21src%21Entity%21File.php/function/File%3A%3AgetFileUri/8.2.x

Desde aquí, podemos ver la clase de la que forma parte, y hay un enlace a ella:

Class

File
Defines the file entity class.

Hacer clic nos lleva a: https://api.drupal.org/api/drupal/core%21modules%21file%21src%21Entity%21File.php/class/File/8.2.x

En su IDE, también puede buscar la \Drupal\file\Entity\Fileclase. Una forma de asegurarse de que esta es la clase correcta es mirar la anotación:

@ContentEntityType(
  id = "file",
  label = @Translation("File"),
  handlers = {
    "storage" = "Drupal\file\FileStorage",
    "storage_schema" = "Drupal\file\FileStorageSchema",
    "access" = "Drupal\file\FileAccessControlHandler",
    "views_data" = "Drupal\file\FileViewsData",
  },
  base_table = "file_managed",
  entity_keys = {
    "id" = "fid",
    "label" = "filename",
    "langcode" = "langcode",
    "uuid" = "uuid"
  }
) 

Observe el id- es file. Presumiblemente, si se está depurando, podría mirar el contenido field_main_video->entityy vería esta ID en alguna parte. Luego solo búscalo en tu IDE. Por lo general, sin embargo, uno sabe lo suficiente sobre los tipos de entidad que está utilizando para adivinar el camino hacia la clase correcta (después de lo cual se puede verificar que la anotación contenga la ID correcta).

En este caso particular, también sé que Filees , probablemente, una clase que se extiende ContentEntityBase, ya que es más como el contenido de la base de datos (una entidad de contenido) de configuración (configuración de una entidad). Entonces, cuando veo que mis suposiciones confirman, eso me ayuda a saber que he encontrado la clase correcta.

En resumen: su IDE, sus debug()declaraciones estratégicas y algunas conjeturas son las mejores formas de descubrir Drupal 8.

Los registros de cambio de PS también pueden ser útiles. Están en https://www.drupal.org/list-changes/drupal

wizonesolutions
fuente
Supongo que el problema del OP es lo contrario: saber qué métodos públicos implementa una clase / tiene disponible.
kiamlaluno
Sí, puede que tenga que volver a leer esto, pero no creo que sea lo que estoy buscando. ¡Estoy tratando de descubrir cómo getFileUri () incluso existe en primer lugar!
Bobby
@Bobby Un archivo es un tipo de entidad, por lo que solo debe mirar su fuente , donde encontrará el método que busca y que está completamente documentado. ¿Es solo que no sabía que un archivo es un tipo de entidad? ¿O que no conoce la convención para ubicar un tipo de entidad en el código? ¿O algo más en la cadena? Hay muchas capas de abstracción para todo en D8, es la forma de Symfony, por lo que hay una gran cantidad de conocimiento "básico" que necesita primero antes de profundizar en el código
Clive
0

Puede usar la función get_class_methods de PHP. El siguiente ejemplo de usuarios carga un archivo:

$image = $form_state->getValue('image_field_name_from_form');
$file = File::load( $image[0] );
$file->setPermanent();
$file->save();

$methods = [];
foreach (get_class_methods($file) as $method) {
        $methods[] = $method;
}
print_r($methods);

Esto agregará todos los métodos disponibles para el archivo de objeto $ en su matriz de $ métodos, que puede imprimir y luego ver todos los métodos disponibles. Esto es válido para cualquier objeto en PHP, no solo Drupal.

Cristian Cordeiro
fuente