利用可能なパブリックメソッドを見つけるにはどうすればよいですか?


9

Drupal 8を使用する上での最大の問題は、必要なデータを取得できないことです。Drupal 8は、オブジェクトを手動でドリルダウンするのではなく、パブリックメソッドを使用することを望んでいます。問題は、使用可能なメソッドのリストを取得するための一貫した方法を理解できないことです。(それらは魔法のように存在し、私はそれらについて知っているだけのように思われます)=

この例では、ビデオフィールドを持つコンテンツタイプがあるとします。そのフィールドで動画ファイルの生のURLを取得する必要があります。

したがって、ノードID($ nid)から始め、どういうわけかノードをロードする方法を理解する必要があります。たくさんの例があるので、これは悪くないです。だから私はのようなことをし$node = \Drupal\node\Entity\Node::load($nid);ます。

ここまでは順調ですね。次に、ビデオフィールド(field_main_video)の値を取得する必要があります。'ネットの周りに矛盾するドキュメントがあるので、これは私が理解するのに永遠にかかりました。最後に、私は次のようなことをしなければならないことを理解しました(これは複数値アイテムであるため)。

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

...次に、配列などをループします。kintを使用しても、これを見つけるのに役立ちませんでした。たとえば、kint($node)メソッドの下を見ると、getValue()がアイテムとして表示されていないからです。それを理解するのに十分な例が周りにあったので、それでもひどくはありません。

しかし、さらに深く見ていくと、ビデオフィールドのエンティティIDを取得してエンティティをロードし、エンティティ内の「uri」フィールドを見つけるのではなく(これは重要な部分です)、知りませんでした。私はD7にいます):この同じコード行ですべてのURIを取得できるメソッドがありました!

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

しかし、どうすればこのgetFileUri()が存在することがわかったのでしょうか。 たまたまブログの投稿で偶然見つけました。これにより、D7よりもURIを簡単に取得できるようになります。

結局、この例で私が求めているのは、オブジェクトの各レベルのすべてのパブリックメソッドを、読みやすく理解しやすい方法でどのように見つけるかです。 手動でapi.drupal.orgを検索したり、IDE固有の何かを使用したりするのではなく、これを行うにはdrupal中心(つまり、開発モジュール)の方法があるはずです。


1
公式ドキュメントはapi.drupal.orgにあります。処理するオブジェクトのクラスを理解すると、継承されたものを含むすべてのメソッドを取得できます。
kiamlaluno

1
...しかし、api.drupal.orgですべてを検索するのではなく、php / develにコマンドで画面に利用可能なメソッドをダンプする方法は確かにありますか?
ボビー

回答:


14

コンテンツエンティティは他のほとんどのものとは異なり、少なくとも構成可能なフィールドについては、メソッドと適切なインターフェイスがないことがよくあります。

コンテンツエンティティとフィールドの場合、パブリックメソッドは実際に知りたいことではなく、フィールドとプロパティについて知りたいことです。そして、参照を介してエンティティに再びアクセスした場合にのみ、メソッドが重要になります。

概要については、優れたEntity APIチートシートを常に参照しています

コンテンツエンティティの構造は固定されています。エンティティ>フィールド(FieldItemList)> FieldItem->プロパティ。プロパティは、スカラーまたは別のものへの参照のいずれかです。たとえば、別のエンティティ、言語オブジェクト、日付オブジェクトなどです。

指定されたいくつかの例について、いくつかの便利なスニペット:

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

いいね!これは少し要約するつもりですが、私はこれが受け入れられた答えであることに傾倒しています。ありがとう!それは質問に正確に答えるものではありませんが、それは私の質問と私の例が2つの異なることを尋ねるようなものだったからです。ありがとうございました!
ボビー

1
@Berdir、これは本当に釘を打つ例の素晴らしいリストです。私はいくつかの情報、どんな情報でもグーグルでした、そしてこれに近いものすらありませんでした。すばらしい答え、本の資料。
Marko Blazekovic 2017年

4

それがあなたの質問に完全に答えるかどうかはわかりませんが、PhpStormのダイアグラム機能を使用することが私に多くの助けになります。

たとえば、階層を示す ここに画像の説明を入力してください

メソッド名も表示するオプションがあります

ここに画像の説明を入力してください

これがあなたの助けになることを願っています。


コマンド+クリック、次にコマンド+ 7でクラスを開くか、[構造]タブをクリックしてクラス構造(プロジェクトのディレクトリビューがある場所)を表示し、UMLを開かずに同じ情報をすばやくスキャンすることもできます。
ケビン

私はphpstormを使用していませんが、今後の参考のために知っておくと役に立ちます。私はこれをdevelやdrupal-centricを使って行う方法を探しています。確かにどこかに何かを建てる必要がありますか?
ボビー

申し訳ありませんが、現時点では、このIDEを使用せずに効率的にAPIをいじることができるとは思いません。
Oleg Videnov 2017年

NetBeansには、いくつかのPHP階層図も含まれています。おそらくそれほどクールではありませんが、NetBeansはフリーソフトウェアであり(PHP Stormはクローズドソースであり、IMHOは高価です)、無料でダウンロードできます。
sanzante 2017年

その価値のあるIDEであれば、これを行うことができます。ところで、PHPStormは、それが提供するものを利用すれば高価ではありません。無料のEAPバージョンを使用できます。オープンソースプロジェクト(Drupalモジュールまたはテーマ)に取り組んでいる場合、JetBrainsは無料のライセンスを提供します。ここでの議論ではありません。
ケビン

4

ええと、私var_dump(get_class_methods($object))は与えられたクラスで利用可能なメソッドのリストを取得するために、の組み合わせをかなり頻繁に使用していることに気付きました。

またapi.drupal.org、詳細についてもよく調べます。


2
これは、私がこれまで探していたものと最も密接に関連している答えのようです。ありがとう!
ボビー

0

あなたはすでにとても近くにいます。

まず、メソッドの定義を見てみましょう:https : //api.drupal.org/api/drupal/core%21modules%21file%21src%21Entity%21File.php/function/File%3A%3AgetFileUri/8.2.x

ここから、これが含まれているクラスを確認でき、それにリンクがあります。

Class

File
Defines the file entity class.

クリックスルーすると、https//api.drupal.org/api/drupal/core%21modules%21file%21src%21Entity%21File.php/class/File/8.2.xに移動します。

IDEでは、\Drupal\file\Entity\Fileクラスを検索することもできます。これが正しいクラスであることを確認する1つの方法は、注釈を調べることです。

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

に注意してくださいid—ですfile。おそらく、デバッグの場合は、その内容を見ることができ、field_main_video->entityどこかにこのIDが表示されます。次に、IDEで検索します。ただし、通常、正しいクラスへの道を推測するために使用しているエンティティタイプについては十分に理解しています(その後、注釈に正しいIDが含まれていることを確認できます)。

この特定のケースでは、私もそれは知ってFileいる、おそらく拡張するクラスContentEntityBase、それはより多くのデータベースの内容(コンテンツ実体)のようなコンフィギュレーション(設定エンティティ)よりもだから、。したがって、私の仮定が確認されると、適切なクラスを見つけたことがわかります。

つまり、簡単に言えば、IDE、戦略的debug()ステートメント、およびいくつかの当て推量は、Drupal 8を発見するための最良の方法です。

PS変更レコードも役立ちます。彼らはであるhttps://www.drupal.org/list-changes/drupal


OPの問題はその逆です。クラスが実装する/利用できるパブリックメソッドを知ることです。
kiamlaluno

ええ、私はこれをもう一度読む必要があるかもしれませんが、それが私が探しているものではないと思います。そもそもgetFileUri()がどのように存在しているかを理解しようとしています!
ボビー

@Bobbyファイルはエンティティタイプであるため、ソースを見るだけでリストされ、完全に文書化された後のメソッドが見つかります。ファイルがエンティティタイプであることを知らなかっただけですか?または、コードでエンティティ型を見つけるための規則を知らないのですか?または、チェーンのさらに上にある何か?D8のすべての抽象化には多くのレイヤーがあり、symfonyの方法であるため、コードを掘り下げる前に最初に必要な「基本」知識がたくさんあります
Clive

0

PHPのget_class_methods関数を使用できます。以下の例では、ファイルのアップロードを使用しています。

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

これにより、オブジェクト$ fileで使用可能なすべてのメソッドが$ methods配列に追加されます。これを印刷して、使用可能なすべてのメソッドを確認できます。これは、Drupalだけでなく、PHPのすべてのオブジェクトに有効です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.