Come trovo i metodi pubblici disponibili?


9

Sto scoprendo che il problema più grande nel lavorare con Drupal 8 è che non riesco a ottenere i dati di cui ho bisogno. Drupal 8 vuole che io usi metodi pubblici piuttosto che eseguire il drill down manuale di un oggetto. Il problema è che non riesco a capire un modo coerente per ottenere un elenco di metodi disponibili! (magicamente esistono, e mi sento come se dovessi conoscerli). =

Per questo esempio, supponiamo che io abbia un tipo di contenuto con un campo video. Devo ottenere l'URL non elaborato del file video in quel campo.

Quindi inizierei con un ID nodo ($ nid) e in qualche modo devo capire come caricare il nodo. Questo non è poi così male perché ci sono molti esempi. Quindi faccio qualcosa del genere $node = \Drupal\node\Entity\Node::load($nid);.

Fin qui tutto bene. Quindi ho bisogno di ottenere il valore del mio campo video (field_main_video). Questo mi ha portato PER SEMPRE a capire perché c'è documentazione contrastante in giro per la rete. Alla fine ho capito che avrei dovuto fare qualcosa del genere (perché è un oggetto multivalore):

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

... poi passa in rassegna l'array, ecc. L'uso di kint non mi ha aiutato a trovarlo. Perché, ad esempio, se io kint($node)e osservo i metodi, non vedo getValue () come un elemento lì. Ancora non terribile, perché c'erano abbastanza esempi in giro per capirlo.

Mentre approfondisco, ciò che non sapevo (questa è la parte importante) era che invece di ottenere l'ID entità del campo video, quindi caricare l'entità, quindi trovare il campo "uri" nell'entità, ecc. (Come Vorrei in D7): c'era un metodo che mi permetteva di ottenere l'URI tutto in questa stessa riga di codice!

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

Ma come avrei potuto sapere che esisteva getFileUri ()? Mi è capitato di imbatterci in un post sul blog. Questo rende davvero più semplice l'ottenimento di un URI rispetto a D7 ... ma solo se si conosce (magicamente) quali metodi esistono per ciascun "livello" di un oggetto.

Alla fine, con questo esempio, chiedo: come trovare tutti i metodi pubblici per ogni livello di un oggetto in un modo che sia facile da leggere e capire? Si noti che sembra che ci dovrebbe essere un modo drupal-centrico (ad es. Modulo di sviluppo) di farlo piuttosto che cercare manualmente api.drupal.org o usare qualcosa di IDE specifico?


1
La documentazione ufficiale è su api.drupal.org. Una volta compresa la classe dell'oggetto che si sta gestendo, si ottengono tutti i metodi, inclusi quelli ereditati.
kiamlaluno

1
... ma piuttosto che cercare tutto su api.drupal.org, sicuramente c'è un modo in php / devel di scaricare i metodi disponibili sullo schermo a comando?
Bobby,

Risposte:


14

Le entità di contenuto sono diverse dalla maggior parte delle altre cose in quanto spesso non dispongono di metodi e interfacce appropriate, almeno non per i campi configurabili.

Nel caso di entità e campi di contenuto, i metodi pubblici non sono realmente ciò che si desidera effettivamente sapere, ciò che si desidera è sapere su campi e proprietà. E solo quando si arriva di nuovo a un'entità attraverso un riferimento, i metodi contano.

Per una panoramica, mi riferisco sempre all'ottimo Cheat Sheet dell'entità Entity .

Le entità di contenuto hanno una struttura fissa, Entità> Campo (FieldItemList)> FieldItem -> Proprietà. Una proprietà è scalare o un riferimento a qualcos'altro, ad esempio un'altra entità, un oggetto linguaggio, un oggetto data, ...

Per alcuni esempi specifici, alcuni frammenti utili:

// 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();
}

Bello! Questo richiederà un po 'di tempo per essere digerito, ma mi sto impegnando perché questa è la risposta accettata. Grazie! Non risponde esattamente alla domanda, ma è solo perché la mia domanda e il mio esempio stavano chiedendo 2 cose diverse. Grazie!
Bobby,

1
@Berdir, questo è un meraviglioso elenco di esempi, che colpisce davvero l'unghia. Ero solo google per qualche informazione, qualsiasi informazione e niente di simile a questo. Ottima risposta, materiale del libro.
Marko Blazekovic,

4

Non sono sicuro se questo risponderà completamente alla tua domanda, ma ciò che mi aiuta molto è usare la funzione diagrammi in PhpStorm.

Ad esempio mostrando la gerarchia inserisci qui la descrizione dell'immagine

Hai opzioni per mostrare anche i nomi dei metodi

inserisci qui la descrizione dell'immagine

Spero che questo ti aiuti in un certo senso.


Puoi anche aprire una classe con comando + clic, quindi comando + 7 o fare clic sulla scheda Struttura per vedere la struttura della classe (dove si troverebbe la vista della directory del progetto) per scansionare rapidamente le stesse informazioni senza aprire UML.
Kevin

Non uso phpstorm, ma è utile sapere come riferimento futuro. Sto cercando un modo per farlo usando devel o qualcosa di drupal-centrico. sicuramente qualcosa deve essere costruito da qualche parte?
Bobby,

Mi dispiace dirlo, ma in questo momento non penso davvero che tu possa armeggiare efficacemente con l'API senza usare questo IDE.
Oleg Videnov,

NetBeans include anche alcuni diagrammi della gerarchia PHP. Probabilmente non è così bello, ma NetBeans è un software gratuito (PHP Storm è chiuso e costoso IMHO) e puoi scaricarlo gratuitamente.
sanzante,

Qualsiasi IDE degno del loro sale può farlo. BTW PHPStorm non è costoso se si utilizza ciò che ha da offrire. Puoi utilizzare la versione EAP gratuita e, se lavori su un progetto open source (moduli o temi Drupal), JetBrains ti darà una licenza gratuita. Non una discussione qui, però.
Kevin,

4

Bene, mi sono ritrovato a usare abbastanza spesso la combinazione di var_dump(get_class_methods($object))avere un elenco di metodi disponibili per la classe data.

Cerco anche abbastanza spesso api.drupal.orgulteriori dettagli.


2
Questa sembra la risposta più strettamente correlata a ciò che stavo cercando finora. Grazie!
Bobby,

0

Sei già molto vicino.

Innanzitutto, diamo un'occhiata alla definizione del metodo: https://api.drupal.org/api/drupal/core%21modules%21file%21src%21Entity%21File.php/function/File%3A%3AgetFileUri/8.2.x

Da qui, possiamo vedere la classe di cui fa parte e c'è un link ad essa:

Class

File
Defines the file entity class.

Fare clic su ci porta a: https://api.drupal.org/api/drupal/core%21modules%21file%21src%21Entity%21File.php/class/File/8.2.x

Nel tuo IDE, puoi anche cercare la \Drupal\file\Entity\Fileclasse. Un modo per essere sicuri che questa sia la classe corretta è guardare l'annotazione:

@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"
  }
) 

Notare il id- lo è file. Presumibilmente, se esegui il debug, potresti guardare il contenuto di field_main_video->entitye vedresti questo ID da qualche parte. Quindi basta cercarlo nel tuo IDE. Di solito, tuttavia, si sa abbastanza sui tipi di entità che si sta utilizzando per indovinare la propria strada verso la classe giusta (dopo di che si potrebbe verificare che l'annotazione contenga l'ID corretto).

In questo caso particolare, so anche che probabilmenteFile è una classe che si estende , dal momento che è più simile al contenuto del database (un'entità di contenuto) che alla configurazione (un'entità di configurazione). Quindi, quando vedo che i miei presupposti confermano, ciò mi aiuta a sapere di aver trovato la classe giusta.ContentEntityBase

Quindi, in breve: l'IDE, le debug()dichiarazioni strategiche e alcune ipotesi sono i modi migliori per scoprire Drupal 8.

Anche i record di modifica PS possono essere utili. Sono su https://www.drupal.org/list-changes/drupal


Prendo il problema del PO è il contrario: sapere quali metodi pubblici una classe implementa / ha a disposizione.
kiamlaluno

Sì, potrei doverlo leggere di nuovo, ma non credo sia quello che sto cercando. Sto cercando di capire come getFileUri () esiste anche in primo luogo!
Bobby,

@Bobby Un file è un tipo di entità, quindi basta guardarne l'origine , dove troverai il metodo che stai dopo elencato e completamente documentato. È solo che non sapevi che un file è un tipo di entità? O che non conosci la convenzione per individuare un tipo di entità nel codice? O qualcos'altro più in alto nella catena? Ci sono molti livelli di astrazione per tutto in D8, è il modo di symfony, quindi c'è molta conoscenza "di base" di cui hai bisogno prima di approfondire il codice
Clive

0

Puoi usare la funzione get_class_methods di PHP. Nell'esempio seguente gli utenti caricano un file:

$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);

Ciò aggiungerà tutti i metodi disponibili all'oggetto $ file nell'array $ method, che è possibile stampare e quindi vedere tutti i metodi disponibili. Questo è valido per qualsiasi oggetto in PHP, non solo per Drupal.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.