[Drupal] Dynamic override key value of configuration entities by Webform Node field value

Jiajun Xu 發表於 週六, 08/24/2019 - 02:24

今天完成了一個讓我鬼打牆了至少整整七天的**小**功能,就是標題寫的這個東西。

我的專案主要是用 Drupal Webform 做課程的線上報名平台。之所以需要做下面這個 custom module,是因為課程報名需要設有人數限制,但 Webform 要設定報名上限的步驟頗為麻煩,而且我也不想讓一般使用者也進去設定頁面,於是決定在 Webform Node content type 裡面新增一個「報名上限」的欄位,讓使用者把上限數字直接填在這裡,再根據這欄位裡的值,去更動對應的 Webform 底下的人數上限設定值。

一、名詞解釋

  • 什麼是 "configuration entities"?

Webform 跟我們熟悉的 Node 不一樣,它是一種 "configuration entity"。我剛看到這個名詞,心裡也只浮現「這是三小???」的感想,就讓我們直接看Drupal 官方文件解釋什麼叫 "configuration"

Configuration API 提供了一個集中地,讓各模組用來儲存他們的組態資料。這些資料可以是 "simple configuration",像是你的網站名稱;而更複雜的資訊,則會使用 "configuration entities" 加以管理,例如 views 或內容類型。

文件也有拿 configuration 跟其他各種 entity types 比較,以及比較 "simple configuration" 和 "configuration entities" 的差別,大家可以看一下

  • 如何使用 configuration?

Drupal 裡的 configuration 以 YAML 格式儲存。我一般要處理 configuration 的時候,習慣使用 drush config 指令,例如有個組態名為 "system.site",我要 print 出它的內容,指令是:drush config:get system.site

內容範例如下:

uuid: 702be758-a110-4x37-bcc0-c5d361591a3c
name: 'Otakupapa Dev'
mail: no_people@otaku.papa.com
slogan: ''
page:
  403: ''
  404: ''
  front: /node
admin_compact_mode: false
weight_select_max: 100
langcode: zh-hant
default_langcode: zh-hant
_core:
  default_config_hash: yTqaBHnEsWxQswufWvkjE8mKw29t8oKuCL1q8KnkfHuGE
  • Webform 的 configuration

前面提到 Webform 是一種 configuration entity,所以每一個 Webform 都有自己的 configuration,其命名方式會是 "webform.webform.{$webform_id}"。

例如有個 Webform 的 id 為 "contact",它的 configuration 就會叫做 "webform.webform.contact"。

  • 什麼是 "Webform Node"?

"Webform Node" 是一種由 Webform 所產生的內容類型,可以把 Webform 依附在頁面中。

二、根據 Webform Node 的欄位值,變更其參照之 Webform 的設定值

廢話不多說,直接秀 code,這是一個 *.module 檔:

use Drupal\node\Entity\Node;
function webform_total_node_presave(Node $node) {
  if ($nodetype == 'webform'){
    $nodetype = $node->bundle();
    $limit_total = $node->get('field_limit_total')->value;
    $ref_webform = $node->get('webform')->target_id;
    $config_id = "webform.webform.{$ref_webform}";
    $config_factory = \Drupal::configFactory();
    $config_factory->getEditable("{$config_id}")->set("settings.limit_total", $limit_total)->save();
  }
}
  • "field_limit_total" 是 Webform Node 裡面,用來讓使用者填寫上限的欄位
  • "settings.limit_total" 是 Webform configuration 裡面,設定報名上限的key。但要注意,它的 YAML 是寫成:
id: contact
title: Contact
description: 'Basic email contact webform.'
(略)
settings:
  ajax: false
  ajax_scroll_top: form
  ajax_progress_type: ''
  ajax_effect: ''
  ajax_speed: null
  ...
  (略)
  ...
  limit_total: 25
  limit_total_interval: null
  ...

是有階層在的喔!所以直接寫 "limit_total" 是無效的,要連它上層的 "settings" 一起寫進去才有效。

標籤 (Tags)