Điểm:4

Làm cách nào để tạo tên thuật ngữ phân loại duy nhất cho mỗi người dùng?

lá cờ cn

Tôi có một vốn từ vựng phân loại, Các nhóm.

Yêu cầu

  • Những người dùng khác nhau có thể tạo các nhóm có cùng tên. (Người dùng A có thể tạo một táo nhóm và Người dùng B cũng có thể tạo một táo tập đoàn.)
  • Cùng một người dùng không thể tạo hai nhóm có cùng tên (Người dùng A không thể tạo hai nhóm táo các nhóm.)

Làm thế nào tôi có thể thực hiện điều này?

D8/9 cung cấp một ràng buộc trường như được giải thích trong câu trả lời nàybài đăng trên blog này, nhưng điều này tạo ra một trường duy nhất cho tất cả người dùng.

tôi muốn làm cho tên thuật ngữ phân loại duy nhất Mỗi người dùng. Ngoài ra, điều này cần phải hoạt động với JSON:API. Tôi có thể làm cái này như thế nào?

Điểm:4
lá cờ cn

Bạn được phép thêm một ràng buộc xác thực tùy chỉnh sử dụng các bước này:

  1. Bước 1: Xác định ràng buộc:

    Định nghĩa ràng buộc sẽ đi vào không gian tên Drupal[MODULENAME]\Plugin\Validation\Constraint, và sẽ mở rộng Symfony\Component\Validator\Constraint. Trong lớp này, các loại vi phạm ràng buộc được xác định, cùng với các thông báo lỗi sẽ được hiển thị cho các vi phạm nhất định.

  2. Bước 2: Tạo xác thực cho ràng buộc

    Bước tiếp theo là tạo lớp sẽ xác thực ràng buộc. Xác thực ràng buộc sẽ đi vào không gian tên Drupal[MODULENAME]\Plugin\Validation\Constraint, và sẽ mở rộng Symfony\Component\Validator\ConstraintValidator. Trong lớp này, các giá trị đã gửi sẽ được trả về và mọi vi phạm sẽ được đăng ký.

    Xin lưu ý rằng tên của lớp trình xác thực của bạn phải là ${ConstraintClassName}Validator theo mặc định. Nếu bạn muốn sử dụng một tên khác, bạn có thể ghi đè lên phương thức validatedBy() của lớp Constraint mà bạn đã tạo ở bước 1.

và đối với bước cuối cùng, bạn có thể thêm ràng buộc mới vào trường của mình giống như câu trả lời bạn đã đề cập

bây giờ có thông tin này, bạn có thể thêm trường tham chiếu người dùng vào phân loại của mình để mỗi thuật ngữ sẽ chứa thông tin về tác giả, bạn có thể sử dụng hook_Entity_Type_presave để đặt trường này theo chương trình

sau đó bạn có thể tạo một ràng buộc tùy chỉnh được gọi là không độc đáoPerArthor (hoặc bất kỳ tên nào bạn thích) thì ở bước 2 nơi bạn xác định phương thức isUniquePerUser, bạn có thể chạy truy vấn và nhận danh sách thuật ngữ phân loại có nhãn bằng giá trị và tác giả bằng với người dùng hiện tại, nếu truy vấn này trả về giá trị thì điều này có nghĩa là thuật ngữ này không phải là duy nhất (người dùng đã xác định thuật ngữ này trước đó) và bạn có thể gây ra lỗi

lá cờ cn
Thật tuyệt vời! Đây có vẻ là một cách tuyệt vời để làm điều đó, ngoại trừ tên thuật ngữ không phải là một trường, phải không? Nó giống như tiêu đề nút/trang-- nó không thể truy cập được (theo như tôi biết) dưới dạng một trường. Vậy tôi phải làm gì trong trường hợp đó?
apaderno avatar
lá cờ us
@PatrickKenny Tiêu đề nút là một trường thực thể: `$fields['title'] = BaseFieldDefinition::create('string')->setLabel(t('Title'))->setRequired(TRUE)->setTranslatable(TRUE )->setRevisionable(TRUE)->setSetting('max_length', 255)->setDisplayOptions('view', ['label' => 'hidden','type' => 'string','weight' => - 5,]);` Đừng nhầm lẫn khi Drupal hiển thị tiêu đề trang trong một khối.
apaderno avatar
lá cờ us
Điều này cũng đúng với tên thuật ngữ phân loại: `$fields['name'] = BaseFieldDefinition::create('string')->setLabel(t('Name'))->setTranslatable(TRUE)->setRevisionable(TRUE )->setRequired(TRUE)->setSetting('max_length', 255)->setDisplayOptions('view', ['label' => 'hidden','type' => 'string','weight' => - 5,]);`
lá cờ cn
@apaderno Cảm ơn, điều đó rất hữu ích. Thật không may, trong `hook_entity_bundle_field_info_alter()`, có vẻ như trường `name` không có sẵn, đây là điều khiến tôi bối rối. Câu hỏi tiếp theo tại đây: https://drupal.stackexchange.com/questions/305789/how-to-set-a-validation-constraint-for-the-taxonomy-term-name
apaderno avatar
lá cờ us
@PatrickKenny Đó là bởi vì `hook_entity_bundle_field_info_alter()` dành cho các trường gói, trong khi tên phân loại là trường cơ sở, có nghĩa là nó có trong mọi gói phân loại.
Alireza Tabatabaeian avatar
lá cờ cn
@PatrickKenny, bạn có thể sử dụng `hook_entity_base_field_info_alter` https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook_entity_base_field_info_alter/8.2.x để thay đổi trường cơ sở các định nghĩa như id hoặc tiêu đề hoặc ...
Điểm:3
lá cờ cn

Cảm ơn @Alireza Tabatabaeian vì điều này. Tôi chỉ đăng mã của mình mà tôi đã sử dụng dựa trên câu trả lời đó.

Đối với phân loại mà tôi muốn áp dụng ràng buộc, tôi đã thêm một trường_term_ref_author thực thể tham chiếu đến người dùng.

mymodule.php

function MYMOUDLE_taxonomy_term_presave(TermInterface $term) {
  $vocabulary = $term->bundle();
  switch ($từ vựng) {
    trường hợp 'my_vocab_type':
      nếu ($term->isNew()) {
        // Đặt tác giả (thông qua trường tùy chỉnh).
        $current_user = \Drupal::currentUser()->id();
        $term->set('field_term_ref_author', $current_user);
      }
    nghỉ;

hàm MYMODULE_entity_base_field_info_alter(&$fields, $entity_type) {
  if ($entity_type->id() === 'taxonomy_term') {
    if (isset($fields['name'])) {
      $fields['name']->addConstraint('TermNameUniquePerUser');
    }
  }
}

mymodule/src/Plugin/Validation/Constraint/TermNameUniquePerUser.php

<?php

không gian tên Drupal\MYMODULE\Plugin\Validation\Constraint;

sử dụng Symfony\Component\Validator\Constraint;

/**
 * Kiểm tra xem giá trị đã gửi là duy nhất cho người dùng.
 *
 * @Hạn chế(
 * id = "TermNameUniquePerUser",
 * nhãn = @Translation("Tên thuật ngữ duy nhất cho mỗi người dùng", ngữ cảnh = "Xác thực"),
 * gõ = "chuỗi"
 * )
 */
lớp TermNameUniquePerUser mở rộng Ràng buộc {
  // Thông báo sẽ được hiển thị nếu giá trị không phải là duy nhất.
  public $notUnique = 'Bạn đã tạo một thuật ngữ có tên %value.';

}

mymodule/src/Plugin/Validation/Constraint/TermNameUniquePerUserValidator.php

<?php

không gian tên Drupal\MYMODULE\Plugin\Validation\Constraint;

sử dụng Symfony\Component\Validator\Constraint;
sử dụng Symfony\Thành phần\Validator\ConstraintValidator;

/**
 * Xác thực ràng buộc TermNameUniquePerUser.
 */
lớp TermNameUniquePerUserValidator mở rộng ConstraintValidator {

  /**
   * {@inheritdoc}
   */
  chức năng công khai xác thực($items, Constraint $constraint) {
    foreach ($items as $item) {
      // Tiếp theo kiểm tra xem giá trị có phải là duy nhất không.
      if (!$this->isUnique($item->value)) {
        $this->context->addViolation($constraint->notUnique, ['%value' => $item->value]);
      }
    }
  }

  /**
   * Là duy nhất?
   *
   * @param chuỗi giá trị $
   */
  hàm riêng isUnique($value) {
    $uid = \Drupal::currentUser()->id();
    $term_name_query = \Drupal::entityQuery('taxonomy_term')
      ->điều kiện('tên', giá trị $, '=')
      ->điều kiện('field_term_ref_author', $uid);
    // Nếu truy vấn có bất kỳ kết quả nào, thì nó không phải là duy nhất.
    // Vì vậy, chúng ta nên trả về điều ngược lại nếu có bất kỳ kết quả nào.
    return !($term_name_query->execute());
  }

}

Điểm hay khi viết truy vấn thực thể như thế này là nếu từ vựng phân loại không có trường_term_ref_author trường, sẽ không bao giờ có bất kỳ kết quả nào, do đó, ràng buộc sẽ đánh giá chính xác các thuật ngữ nằm trong các gói không tuân theo ràng buộc (mặc dù điều này sẽ dẫn đến truy vấn cơ sở dữ liệu lãng phí.)

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.