ฉันดูเพิ่มเติม แต่ไม่พบเอกสารที่อธิบายสิ่งนี้จริงๆ
สิ่งที่ฉันต้องการคือวิธีเข้าร่วมตารางผู้ใช้กับอีกสองตารางที่เก็บข้อมูลสำหรับผู้ใช้ อย่างไรก็ตามตารางอีกสองตารางนั้นอยู่ในความสัมพันธ์แบบหนึ่งต่อหลายกับตารางผู้ใช้ซึ่งหมายความว่าฉันจะจบลงด้วยการเข้าร่วมคาร์ทีเซียนถ้าฉันพยายามที่จะเข้าร่วมตารางผู้ใช้ที่มีทั้งสองตารางในเวลาเดียวกัน . อย่างไรก็ตามเนื่องจากทั้งหมดที่ฉันต้องการคือการนับจำนวนระเบียนในสองตารางอื่น ๆ ที่เกี่ยวข้องกับผู้ใช้ที่กำหนดใด ๆ แบบสอบถามย่อยควรจะสามารถหลอกลวง อย่างไรก็ตามฉันไม่พบเอกสารใด ๆ เกี่ยวกับ Views และเคียวรีย่อย - ดังนั้นนี่คือสิ่งที่ฉันทำ
- สร้างเขตจำลองสองฟิลด์
ฉันสร้างเขตข้อมูลจำลองสองฟิลด์ (ซึ่งฉันจะเรียกว่า 'ดาวน์โหลด' และ 'ฟัง') ผ่าน hook_views_data () คำจำกัดความของฟิลด์แสดงอยู่ด้านล่าง
function hook_views_data() {
$data['users'] = array(
'downloads' => array(
'title' => t('Downloads'),
'field' => array(
'handler' => 'views_handler_field_numeric',
'click sortable' => TRUE,
),
'filter' => array(
'handler' => 'views_handler_filter_numeric',
),
'sort' => array(
'handler' => 'views_handler_sort',
),
),
'listens' => array(
'title' => t('Listens'),
'field' => array(
'handler' => 'views_handler_field_numeric',
'click sortable' => TRUE,
),
'filter' => array(
'handler' => 'views_handler_filter_numeric',
),
'sort' => array(
'handler' => 'views_handler_sort',
),
)
),
);
ตอนนี้เมื่อคุณกำหนดค่ามุมมองสำหรับผู้ใช้ฟิลด์ 'ดาวน์โหลด' และ 'ฟัง' จะปรากฏขึ้น อย่างไรก็ตามการพยายามเรียกใช้คิวรีในขณะนี้จะส่งผลให้เกิดข้อผิดพลาดเนื่องจากเขตข้อมูลจำลองหลังจากทั้งหมดเป็นเขตจำลอง พวกเขาไม่อยู่ จุดประสงค์เดียวของฟิลด์เหล่านี้คือการส่งสัญญาณไปยังการใช้งาน hook_views_query_alter () ของเราซึ่งจำเป็นต้องทำอุปกรณ์ทดแทนสองสามตัว
- ใช้ hook_views_query_alter ()
เคล็ดลับที่นี่คือการตรวจสอบว่าแบบสอบถามที่ระบุนั้นรวมฟิลด์ 'ดาวน์โหลด' หรือ 'ฟัง' หากเป็นเช่นนั้นเราจะลบเขตข้อมูลออกจากแบบสอบถามและแทนที่ด้วยแบบสอบถามย่อย การใช้งานฟังก์ชั่นนี้มีดังนี้
function mta_views_query_alter(&$view, &$query) {
foreach ($query->fields as $field_key => &$field_values) {
if ($field_values['table'] == 'users') {
switch ($field_values['field']) {
case 'downloads':
unset($query->fields[$field_key]);
$query->add_field(null, "(SELECT COUNT(*) FROM {fileusage} fu WHERE fu.externaluser = {users}.uid AND fu.action = 0)", $field_key);
break;
case 'listens':
unset($query->fields[$field_key]);
$query->add_field(null, "(SELECT COUNT(*) FROM {fileusage} fu WHERE fu.externaluser = {users}.uid AND fu.action = 1)", $field_key);
break;
}
}
}
}
โปรดทราบว่าเรากำลังใช้นามแฝงของฟิลด์ที่ลบออกสำหรับการค้นหาย่อยอีกครั้ง ด้วยวิธีนี้ Views จะคิดว่าค่าที่ส่งคืนจากแบบสอบถามย่อยนั้นจริงมาจากเขตข้อมูลจำลอง (ซึ่งหลังจากไม่มีอยู่จริง)
นั่นคือ. เราไม่ได้รับการเข้าร่วมคาร์ทีเซียนและจะนับทั้ง 'ดาวน์โหลด' และ 'ฟัง' อย่างถูกต้อง