ฉันจะค้นหาวิธีสาธารณะที่มีอยู่ได้อย่างไร


9

ฉันพบว่าปัญหาที่ใหญ่ที่สุดในการทำงานกับ Drupal 8 คือฉันไม่สามารถรับข้อมูลที่ต้องการได้ Drupal 8 ต้องการให้ฉันใช้วิธีสาธารณะแทนที่จะเจาะลึกวัตถุด้วยตนเอง ปัญหาคือฉันไม่สามารถหาวิธีที่สอดคล้องกันในการรับรายการวิธีการที่ใช้ได้! (พวกเขามีอยู่อย่างน่าอัศจรรย์และฉันรู้สึกว่าฉันควรจะรู้เกี่ยวกับพวกเขา)

สำหรับตัวอย่างนี้สมมติว่าฉันมีประเภทเนื้อหาที่มีฟิลด์วิดีโอ ฉันต้องได้รับ URL ดิบของไฟล์วิดีโอในฟิลด์นั้น

ดังนั้นฉันจะเริ่มต้นด้วย node 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 () เป็นรายการที่มี ยังคงไม่น่ากลัวเพราะมีตัวอย่างเพียงพอที่จะคิดออก

ในขณะที่ฉันไปให้ลึกกว่านั้นสิ่งที่ฉันไม่รู้ (นี่คือส่วนสำคัญ) ก็คือแทนที่จะได้รับรหัสเอนทิตีของฟิลด์วิดีโอแล้วโหลดเอนทิตีแล้วค้นหาเอนทิตี "uri" ในเอนทิตี้ ฯลฯ (เช่น ฉันจะเป็น D7): มีวิธีที่ทำให้ฉันได้รับ URI ทั้งหมดในรหัสบรรทัดเดียวกันนี้!

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

แต่ฉันจะรู้ได้อย่างไรว่า getFileUri () นี้มีอยู่จริง? ฉันบังเอิญพบมันในโพสต์บล็อก สิ่งนี้ทำให้การได้รับ URI ง่ายกว่าใน D7 ... แต่ถ้าคุณรู้ (อย่างน่าอัศจรรย์) วิธีการที่มีอยู่สำหรับ 'ระดับ' ของแต่ละวัตถุ

ในท้ายที่สุดจากตัวอย่างนี้ฉันถามว่า: คุณจะหาวิธีการสาธารณะทั้งหมดสำหรับแต่ละระดับของวัตถุในวิธีที่ง่ายต่อการอ่านและทำความเข้าใจอย่างไร โปรดทราบว่าดูเหมือนว่าควรมี drupal-centric (เช่นโมดูล devel) ในการทำสิ่งนี้แทนที่จะค้นหาด้วยตนเอง api.drupal.org หรือใช้บางสิ่งบางอย่างที่เฉพาะเจาะจงของ IDE?


1
เอกสารอย่างเป็นทางการอยู่ที่ api.drupal.org เมื่อคุณเข้าใจคลาสของวัตถุที่คุณกำลังจัดการคุณจะได้รับวิธีการทั้งหมดรวมถึงวัตถุที่สืบทอดมา
kiamlaluno

1
... แต่แทนที่จะค้นหาทุกอย่างใน api.drupal.org แน่นอนว่ามีวิธีใน php / devel ในการถ่ายโอนวิธีการที่มีอยู่ไปยังหน้าจอเมื่อมีคำสั่ง?
Bobby

คำตอบ:


14

เอนทิตีเนื้อหาแตกต่างจากสิ่งอื่น ๆ ส่วนใหญ่ซึ่งมักจะไม่มีวิธีการและอินเทอร์เฟซที่เหมาะสมอย่างน้อยก็ไม่ใช่ฟิลด์ที่กำหนดค่าได้

ในกรณีของเอนทิตีและฟิลด์เนื้อหาเมธอดสาธารณะไม่ใช่สิ่งที่คุณต้องการทราบอย่างแท้จริงสิ่งที่คุณต้องการคือรู้เกี่ยวกับฟิลด์และคุณสมบัติ และเมื่อคุณได้รับเอนทิตีอีกครั้งผ่านการอ้างอิงแล้ววิธีการที่สำคัญ

สำหรับภาพรวมฉันมักจะอ้างถึงEntity API Cheat Sheetที่ยอดเยี่ยมเสมอ

เอนทิตีเนื้อหามีโครงสร้างแบบคงที่เอนทิตี> ฟิลด์ (FieldItemList)> FieldItem -> Property คุณสมบัติเป็นแบบเกลาหรือการอ้างอิงถึงสิ่งอื่นเช่นเอนทิตีอื่น, วัตถุภาษา, วัตถุวันที่, ...

สำหรับตัวอย่างที่ระบุบางตัวอย่างตัวอย่างที่มีประโยชน์:

// 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 นี่เป็นรายการตัวอย่างที่น่ากลัว ฉันแค่ google เพื่อรับข้อมูลข้อมูลใด ๆ และไม่มีอะไรใกล้เคียงกับสิ่งนี้ คำตอบที่ดีวัสดุหนังสือ
Marko Blazekovic

4

ไม่แน่ใจว่าจะตอบคำถามของคุณได้อย่างสมบูรณ์ แต่สิ่งที่ช่วยฉันได้มากคือการใช้คุณสมบัติไดอะแกรมใน PhpStorm

ตัวอย่างเช่นแสดงลำดับชั้น ป้อนคำอธิบายรูปภาพที่นี่

คุณมีตัวเลือกเพื่อแสดงชื่อวิธีการ

ป้อนคำอธิบายรูปภาพที่นี่

ฉันหวังว่านี่จะช่วยคุณได้


คุณยังสามารถเปิดคลาสด้วยคำสั่ง + คลิกจากนั้นคำสั่ง + 7 หรือคลิกแท็บโครงสร้างเพื่อดูโครงสร้างคลาส (ซึ่งมุมมองไดเรกทอรีโครงการของคุณจะเป็น) เพื่อสแกนข้อมูลเดียวกันโดยไม่ต้องเปิด UML
Kevin

ฉันไม่ได้ใช้ phpstorm แต่เป็นการดีที่จะทราบสำหรับการอ้างอิงในอนาคต ฉันกำลังมองหาวิธีในการทำเช่นนี้โดยใช้ devel หรือบางสิ่งบางอย่าง drupal-centric ต้องสร้างบางสิ่งในที่ใดบ้าง?
Bobby

ฉันขอโทษที่ต้องบอกว่า แต่ฉันไม่คิดว่าตอนนี้คุณสามารถคนจรจัดกับ API ได้อย่างมีประสิทธิภาพโดยไม่ต้องใช้ IDE นี้
Oleg Videnov

NetBeans ยังมีไดอะแกรมลำดับชั้นของ PHP อีกด้วย อาจจะไม่เจ๋งนัก แต่ NetBeans เป็นซอฟต์แวร์เสรี (PHP Storm ปิดแหล่งที่มาและราคาแพง IMHO) และคุณสามารถดาวน์โหลดได้ฟรี
sanzante

IDE ที่มีค่าเกลือสามารถทำได้ BTW PHPS รูปแบบไม่แพงถ้าคุณใช้สิ่งที่มีให้ คุณสามารถใช้รุ่น EAP ฟรีและหากคุณทำงานในโครงการโอเพนซอร์ส (โมดูลหรือธีม Drupal) 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->entityและคุณจะเห็น ID นี้ที่ไหนสักแห่ง จากนั้นคุณเพียงค้นหาใน IDE ของคุณ อย่างไรก็ตามโดยปกติแล้วมีใครรู้มากพอเกี่ยวกับประเภทเอนทิตีหนึ่งที่ใช้ในการเดาทางไปยังคลาสที่ถูกต้อง

เฉพาะในกรณีนี้ผมยังไม่ทราบว่าFileเป็นอาจจะเป็นระดับที่ขยายContentEntityBaseเพราะมันมากขึ้นเช่นเนื้อหาของฐานข้อมูล (เป็นนิติบุคคลเนื้อหา) มากกว่าการกำหนดค่า (การกำหนดค่านิติบุคคล) ดังนั้นเมื่อฉันเห็นสมมติฐานของฉันยืนยันนั่นจะช่วยให้ฉันรู้ว่าฉันได้พบชั้นเรียนที่เหมาะสม

ดังนั้นโดยย่อ: IDE ของคุณdebug()ข้อความเชิงกลยุทธ์และการคาดเดาบางอย่างเป็นวิธีที่ดีที่สุดในการค้นหา Drupal 8

บันทึกการเปลี่ยนแปลง 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 ซึ่งคุณสามารถพิมพ์แล้วดูวิธีการทั้งหมดที่มีอยู่ สิ่งนี้ใช้ได้สำหรับวัตถุใด ๆ ใน PHP ไม่ใช่แค่ Drupal

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.