사용 가능한 공개 방법을 찾으려면 어떻게합니까?


9

Drupal 8을 사용할 때 가장 큰 문제는 필요한 데이터를 얻을 수 없다는 것입니다. Drupal 8은 객체를 통해 수동으로 드릴 다운하는 대신 공용 메소드를 사용하기를 원합니다. 문제는 사용 가능한 방법 목록을 얻는 일관된 방법을 알 수 없다는 것입니다! (마 법적으로 존재하며, 나는 그들에 대해 알아야한다고 생각합니다). =

이 예제에서는 비디오 필드가있는 컨텐츠 유형이 있다고 가정하겠습니다. 해당 필드에 비디오 파일의 원시 URL을 가져와야합니다.

그래서 노드 ID ($ nid)로 시작하고 어떻게 든 노드를로드하는 방법을 알아야합니다. 많은 예제가 있기 때문에 이것은 나쁘지 않습니다. 그래서 나는 같은 것을 $node = \Drupal\node\Entity\Node::load($nid);합니다.

여태까지는 그런대로 잘됐다. 그런 다음 비디오 필드의 값을 가져와야합니다 (field_main_video). 'net 주위에 충돌하는 문서가 있기 때문에 이것을 알아 내야했습니다. 마지막으로 나는 다중 값 항목이기 때문에 이와 같은 작업을 수행해야한다는 것을 알았습니다.

$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-centric (즉, devel 모듈) 방법이 있어야합니다.


1
공식 문서는 api.drupal.org에 있습니다. 처리중인 객체의 클래스를 이해하면 상속 된 객체를 포함한 모든 메소드를 얻습니다.
kiamlaluno

1
...하지만 api.drupal.org에서 모든 것을 찾는 것이 아니라, php / devel에서 사용 가능한 메소드를 명령 화면에 덤프하는 방법이 있습니까?
Bobby

답변:


14

컨텐트 엔터티는 구성 가능한 필드에 대해 최소한 메서드와 적절한 인터페이스를 가지고 있지 않다는 점에서 대부분의 다른 요소와 다릅니다 .

컨텐트 엔터티와 필드의 경우 공용 메서드는 실제로 실제로 알고 싶은 것이 아니라 필드와 속성에 대해 알고 싶은 것입니다. 그리고 참조를 통해 엔티티에 다시 도달 할 때만 메소드가 중요합니다.

개요를 위해, 나는 항상 위대한 엔티티 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 가지 다른 것을 요구했기 때문입니다. 감사합니다!
Bobby

1
@ Berdir, 이것은 손톱을 실제로 때리는 예제의 끔찍한 목록입니다. 나는 정보, 정보 및 이것에 가까운 아무것도 구글에 불과했습니다. 훌륭한 답변, 도서 자료.
Marko Blazekovic

4

이것이 귀하의 질문에 완전히 대답할지 확실하지 않지만 PhpStorm의 다이어그램 기능을 사용하는 것이 많은 도움이됩니다.

예를 들어 계층을 보여주는 여기에 이미지 설명을 입력하십시오

메소드 이름도 표시하는 옵션이 있습니다

여기에 이미지 설명을 입력하십시오

이것이 도움이 되었기를 바랍니다.


명령 + 클릭으로 클래스를 열거 나 명령 +7을 클릭하거나 구조 탭을 클릭하여 UML을 열지 않고도 동일한 정보를 신속하게 스캔하는 클래스 구조 (프로젝트 디렉토리보기가있는 위치)를 볼 수 있습니다.
Kevin

나는 phpstorm을 사용하지 않지만 나중에 참조 할 수있는 것이 좋습니다. devel 또는 drupal-centric을 사용 하여이 작업을 수행 할 수있는 방법을 찾고 있습니다. 반드시 어딘가에 무언가를 만들어야합니까?
Bobby

유감스럽게도, 현재로서는이 IDE를 사용하지 않고 API를 효율적으로 땜질 할 수 있다고 생각하지 않습니다.
Oleg Videnov

NetBeans에는 일부 PHP 계층 다이어그램이 포함되어 있습니다. 아마도 그렇게 시원하지는 않지만 NetBeans는 자유 소프트웨어이며 (PHP Storm은 폐쇄 소스이며 IMHO는 비싸다) 무료로 다운로드 할 수있다.
sanzante

소금의 가치가있는 모든 IDE가이를 수행 할 수 있습니다. BTW PHPStorm은 제공하는 것을 활용하면 비싸지 않습니다. 무료 EAP 버전을 사용할 수 있으며 오픈 소스 프로젝트 (중복 모듈 또는 테마)에서 작업하는 경우 JetBrains가 무료 라이센스를 부여합니다. 그러나 여기에 대한 토론은 없습니다.
Kevin

4

글쎄, 나는 var_dump(get_class_methods($object))주어진 클래스에 사용 가능한 메소드 목록을 갖기 위해 종종 조합을 사용하는 것을 발견했다 .

또한 api.drupal.org자세한 내용은 자주 확인합니다.


2
이것은 지금까지 내가 찾던 것과 가장 밀접하게 관련된 답변 인 것 같습니다. 감사!
Bobby

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클래스를 검색 할 수도 있습니다 . 이것이 올바른 클래스인지 확인하는 한 가지 방법은 주석을 보는 것입니다.

@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->entityID가 어딘가에 나타납니다. 그런 다음 IDE에서 검색하십시오. 그러나 일반적으로 올바른 클래스로가는 길을 추측하기 위해 사용하는 엔티티 유형에 대해 충분히 알고 있습니다 (그 후에 주석에 올바른 ID가 포함되어 있는지 확인할 수 있음).

이 특정한 경우에, 나는 또한 알고 File있습니다 아마 확장하는 클래스 ContentEntityBase가 더 구성 이상의 데이터베이스 내용 (콘텐츠 엔티티) (구성 개체)와 같은 이후. 따라서 내 가정이 확인되면 올바른 수업을 찾았 음을 알 수 있습니다.

간단히 말해 debug(), Drupal 8을 발견하는 가장 좋은 방법은 IDE, 전략적 진술 및 일부 추측이 있습니다.

PS 변경 기록도 도움이 될 수 있습니다. 그들은 https://www.drupal.org/list-changes/drupal에 있습니다


OP의 문제는 그 반대입니다. 클래스가 구현 / 사용 가능한 공용 메소드를 아는 것입니다.
kiamlaluno

그래, 나는 이것을 다시 읽어야 할지도 모르지만 그것이 내가 찾고있는 것이라고 생각하지 않는다. getFileUri ()가 처음에 어떻게 존재하는지 알아 내려고 노력하고 있습니다!
Bobby

@Bobby 파일은 엔터티 유형이므로 소스 만 살펴보십시오. 여기에서 목록을 작성하고 완전히 문서화 된 방법을 찾을 수 있습니다. 파일이 엔티티 유형인지 몰랐다는 것입니까? 또는 코드에서 엔터티 유형을 찾는 규칙을 모르십니까? 아니면 다른 일이 더 있습니까? D8에는 모든 것에 대한 추상화 계층이 많이 있습니다. 심포니 방식이므로 코드를 파기 전에 먼저 필요한 "기본"지식이 많이 있습니다.
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.