Làm thế nào để tôi tìm thấy các phương pháp công cộng có sẵn?


9

Tôi thấy rằng vấn đề lớn nhất khi làm việc với Drupal 8 là tôi không thể có được dữ liệu mình cần. Drupal 8 muốn tôi sử dụng các phương thức công khai hơn là tự mình đi sâu vào một đối tượng. Vấn đề là, tôi không thể tìm ra một cách nhất quán để có được danh sách các phương pháp có sẵn! (chúng tồn tại một cách kỳ diệu và tôi cảm thấy như mình chỉ cần biết về chúng). =

Trong ví dụ này, giả sử tôi có loại nội dung với trường video. Tôi cần lấy URL thô của tệp video trong trường đó.

Vì vậy, tôi bắt đầu với một id nút ($ nid) và bằng cách nào đó tôi phải tìm ra cách tải nút. Điều này không quá tệ vì có rất nhiều ví dụ. Vì vậy, tôi làm một cái gì đó như $node = \Drupal\node\Entity\Node::load($nid);.

Càng xa càng tốt. Sau đó, tôi cần lấy giá trị của trường video của mình (field_main_video). Điều này khiến tôi TUYỆT ĐỐI để tìm ra vì có tài liệu mâu thuẫn trên mạng. Cuối cùng tôi đã tìm ra rằng tôi phải làm một cái gì đó như thế này (vì đó là một mặt hàng đa giá trị):

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

... sau đó lặp qua mảng, v.v ... Sử dụng kint cũng không giúp tôi tìm thấy cái này. Bởi vì, ví dụ, nếu tôi kint($node)và xem theo các phương thức, tôi không thấy getValue () là một mục ở đó. Vẫn không khủng khiếp, vì có đủ ví dụ xung quanh để tìm ra nó.

Tuy nhiên, khi tôi đi sâu hơn, điều tôi không biết (đây là phần quan trọng) là thay vì lấy id thực thể trường video, sau đó tải thực thể, sau đó tìm trường "uri" trong thực thể, v.v. Tôi sẽ ở D7): Có một phương pháp cho phép tôi lấy tất cả URI trong cùng dòng mã này!

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

Nhưng làm thế nào tôi có thể biết getFileUri () này tồn tại? Tôi tình cờ vấp phải nó trong một bài viết trên blog. Điều này thực sự làm cho việc nhận URI dễ dàng hơn trong D7 ... nhưng chỉ khi bạn biết (một cách kỳ diệu) phương thức nào tồn tại cho mỗi 'cấp độ' của một đối tượng.

Cuối cùng, với ví dụ này tôi đang hỏi: Làm thế nào để bạn tìm thấy tất cả các phương thức công khai cho từng cấp độ của một đối tượng theo cách dễ đọc và dễ hiểu? Lưu ý rằng có vẻ như nên có một cách drupal-centric (ví dụ: mô-đun devel) để thực hiện việc này thay vì tìm kiếm thủ công api.drupal.org hoặc sử dụng một cái gì đó cụ thể IDE?


1
Tài liệu chính thức có tại api.drupal.org. Khi bạn hiểu được lớp của đối tượng bạn đang xử lý, bạn sẽ có được tất cả các phương thức, bao gồm cả các phương thức được kế thừa.
kiamlaluno

1
... nhưng thay vì tìm kiếm mọi thứ trên api.drupal.org, chắc chắn có một cách trong php / devel để kết xuất các phương thức có sẵn vào màn hình theo lệnh?
Bobby

Câu trả lời:


14

Các thực thể nội dung khác với hầu hết những thứ khác ở chỗ chúng thường không có phương thức và giao diện phù hợp, ít nhất là không dành cho các trường có thể định cấu hình.

Trong trường hợp các thực thể và trường nội dung, các phương thức công khai không thực sự là những gì bạn thực sự muốn biết, điều bạn muốn là biết về các trường và thuộc tính. Và chỉ khi bạn trở lại một thực thể thông qua một tham chiếu thì các phương thức mới quan trọng.

Để biết tổng quan, tôi luôn tham khảo Bảng cheat API thực thể tuyệt vời .

Các thực thể nội dung có cấu trúc cố định, Thực thể> Trường (FieldItemList)> FieldItem -> Thuộc tính. Một thuộc tính là vô hướng hoặc tham chiếu đến một thứ khác, ví dụ như một thực thể khác, một đối tượng ngôn ngữ, một đối tượng ngày, ...

Đối với một vài ví dụ cụ thể, một số đoạn hữu ích:

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

Đẹp! Điều này sẽ mất một chút để tiêu hóa, nhưng tôi đang nghiêng về phía đây là câu trả lời được chấp nhận. Cảm ơn! Nó không trả lời chính xác câu hỏi nhưng đó chỉ bởi vì câu hỏi của tôi và ví dụ của tôi là loại hỏi 2 điều khác nhau. Cảm ơn bạn!
Bobby

1
@Berdir, đây là danh sách ví dụ tuyệt vời, đánh móng tay thực sự. Tôi chỉ là google cho một số thông tin, bất kỳ thông tin và thậm chí không có gì gần với điều này. Câu trả lời tuyệt vời, tài liệu sách.
Marko Blazekovic

4

Không chắc chắn nếu điều đó sẽ trả lời hoàn toàn câu hỏi của bạn nhưng điều giúp tôi rất nhiều là sử dụng tính năng sơ đồ trong PhpStorm.

Ví dụ: hiển thị thứ bậc nhập mô tả hình ảnh ở đây

Bạn có các tùy chọn để hiển thị tên phương thức

nhập mô tả hình ảnh ở đây

Tôi hy vọng điều này sẽ giúp bạn một cách.


Bạn cũng có thể mở một lớp bằng lệnh + nhấp, sau đó ra lệnh + 7 hoặc bấm vào tab Cấu trúc để xem cấu trúc lớp (nơi có dạng xem thư mục dự án của bạn) để quét nhanh thông tin tương tự mà không cần mở UML.
Kevin

Tôi không sử dụng phpstorm, nhưng điều này là tốt để biết để tham khảo trong tương lai. Tôi đang tìm kiếm một cách để làm điều này bằng cách sử dụng devel hoặc một cái gì đó trung tâm. chắc chắn một cái gì đó phải được xây dựng ở đâu đó?
Bobby

Tôi rất tiếc phải nói điều đó, nhưng tôi thực sự không nghĩ rằng tại thời điểm này bạn có thể sửa đổi API một cách hiệu quả mà không cần sử dụng IDE này.
Oleg Videnov

NetBeans cũng bao gồm một số sơ đồ phân cấp PHP. Có lẽ không thú vị lắm, nhưng NetBeans là Phần mềm miễn phí (PHP Storm là nguồn đóng và IMHO đắt tiền) và bạn có thể tải xuống miễn phí.
sanzante

Bất kỳ IDE giá trị muối của họ có thể làm điều này. BTW PHPStorm không đắt nếu bạn sử dụng những gì nó cung cấp. Bạn có thể sử dụng phiên bản EAP miễn phí và nếu bạn làm việc trong một dự án nguồn mở (mô-đun hoặc chủ đề Drupal), JetBrains sẽ cấp cho bạn giấy phép miễn phí. Không phải là một cuộc thảo luận cho ở đây mặc dù.
Kevin

4

Chà, tôi thấy mình sử dụng khá thường xuyên sự kết hợp var_dump(get_class_methods($object))để có một danh sách các phương thức có sẵn cho lớp đã cho.

Tôi cũng nhìn khá thường xuyên api.drupal.orgđể biết thêm chi tiết.


2
Đây dường như là câu trả lời gần nhất liên quan đến những gì tôi đang tìm kiếm cho đến nay. Cảm ơn!
Bobby

0

Bạn đã rất gần rồi.

Trước tiên, hãy xem định nghĩa của phương thức: https://api.drupal.org/api/drupal/core%21modules%21file%21src%21Entity%21File.php/feft/File%3A%3AgetFileUri/8.2.x

Từ đây, chúng ta có thể thấy lớp này là một phần của nó, và có một liên kết đến nó:

Class

File
Defines the file entity class.

Nhấp qua sẽ đưa chúng tôi đến: https://api.drupal.org/api/drupal/core%21modules%21file%21src%21Entity%21File.php/ class / File / 8.x.x

Trong IDE của bạn, bạn cũng có thể tìm kiếm \Drupal\file\Entity\Filelớp. Một cách để chắc chắn đây là lớp đúng là nhìn vào chú thích:

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

Lưu ý rằng id- nó là file. Có lẽ, nếu gỡ lỗi, bạn có thể xem nội dung field_main_video->entityvà bạn sẽ thấy ID này ở đâu đó. Sau đó, bạn chỉ cần tìm kiếm nó trong IDE của bạn. Tuy nhiên, thông thường, người ta biết đủ về các loại thực thể mà người ta đang sử dụng để đoán một cách đến đúng lớp (sau đó người ta có thể xác minh rằng chú thích có chứa ID chính xác).

Trong trường hợp đặc biệt này, tôi cũng biết rằng Filelẽ một lớp mà kéo dài ContentEntityBase, vì nó giống như nội dung cơ sở dữ liệu (một tổ chức nội dung) so với cấu hình (một thực thể cấu hình). Vì vậy, khi tôi thấy các giả định của mình xác nhận, điều đó giúp tôi biết rằng tôi đã tìm đúng lớp.

Vì vậy, trong ngắn hạn: IDE của bạn, debug()báo cáo chiến lược và một số phỏng đoán là cách tốt nhất để khám phá Drupal 8.

Hồ sơ thay đổi PS cũng có thể hữu ích. Họ đang ở https://www.drupal.org/list-changes/drupal


Tôi coi vấn đề của OP là ngược lại: biết phương thức công khai nào mà lớp thực hiện / có sẵn.
kiamlaluno

Vâng, tôi có thể phải đọc lại, nhưng tôi không nghĩ đó là thứ tôi đang tìm kiếm. Tôi đang cố gắng tìm hiểu làm thế nào getFileUri () thậm chí tồn tại ở nơi đầu tiên!
Bobby

@Bulk Một tệp là một loại thực thể, vì vậy bạn chỉ cần xem nguồn của nó , nơi bạn sẽ tìm thấy phương pháp mà bạn đã liệt kê và ghi lại đầy đủ. Có phải là bạn không biết một tập tin là một loại thực thể? Hoặc bạn không biết quy ước định vị một loại thực thể trong mã? Hoặc một cái gì đó khác lên chuỗi? Có nhiều lớp trừu tượng cho mọi thứ trong D8, đó là cách giao tiếp, vì vậy, có rất nhiều kiến ​​thức "cơ bản" bạn cần trước tiên trước khi đào sâu vào mã
Clive

0

Bạn có thể sử dụng hàm PHP get_group_methods. Ví dụ bên dưới người dùng tải lên tệp:

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

Điều này sẽ thêm tất cả các phương thức có sẵn cho đối tượng $ file vào mảng phương thức $ của bạn, mà bạn có thể in và sau đó xem tất cả các phương thức có sẵn. Điều này hợp lệ cho bất kỳ đối tượng nào trong PHP, không chỉ Drupal.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.