Drupal 7 में डेटाबेस के साथ काम — पाठ 6 — रनटाइम पर क्वेरी संशोधन (hook_query_alter)
ड्रुपल 7 में डायनेमिक SELECT क्वेरी की एक महत्वपूर्ण विशेषता यह है कि अन्य मॉड्यूल्स रनटाइम पर (यानी “ऑन द फ्लाई”) क्वेरी को संशोधित कर सकते हैं। इससे दूसरे मॉड्यूल्स अपने निर्देश क्वेरी में जोड़ सकते हैं, ताकि वे इसके व्यवहार को बदल सकें — उदाहरण के लिए, नोड एक्सेस नियंत्रण लागू करना या डेटा फ़िल्टरिंग बदलना। रनटाइम क्वेरी परिवर्तन की प्रक्रिया तीन घटकों पर आधारित होती है: tagging, meta data, और hook_query_alter()।
Tagging (टैगिंग)
किसी भी डायनेमिक SELECT क्वेरी को एक या अधिक स्ट्रिंग टैग्स के साथ “टैग” किया जा सकता है। ये टैग यह पहचानने में मदद करते हैं कि यह क्वेरी किस प्रकार की है और कौन-सा मॉड्यूल उस पर क्रिया कर सकता है। टैग हमेशा लोअरकेस अल्फ़ान्यूमेरिक (a-z, 0-9, अंडरस्कोर सहित) होने चाहिए — ठीक वैसे ही जैसे PHP वेरिएबल्स। टैग जोड़ने के लिए addTag() मेथड का उपयोग किया जाता है:
<?php $query->addTag('node_access'); ?>
किसी क्वेरी ऑब्जेक्ट में टैग मौजूद है या नहीं, यह जाँचने के लिए आप निम्नलिखित मेथड्स का उपयोग कर सकते हैं:
<?php // TRUE लौटाएगा, यदि क्वेरी में दिया गया टैग मौजूद है। $query->hasTag('example'); // TRUE, यदि क्वेरी में सभी निर्दिष्ट टैग्स मौजूद हैं। $query->hasAllTags('example1', 'example2'); // TRUE, यदि क्वेरी में कोई भी निर्दिष्ट टैग मौजूद है। $query->hasAnyTag('example1', 'example2'); ?>
hasAllTags() और hasAnyTag() दोनों कई पैरामीटर्स स्वीकार करते हैं, और उनका क्रम मायने नहीं रखता।
Drupal में पहले से कई सामान्य टैग्स उपयोग के लिए मौजूद हैं, जैसे:
- node_access
- क्वेरी में नोड्स के लिए एक्सेस नियंत्रण जोड़ा जाएगा।
- translatable
- क्वेरी में अनुवाद योग्य (translatable) स्ट्रिंग्स शामिल की जाएँगी।
- term_access
- क्वेरी में टैक्सोनॉमी टर्म्स के लिए एक्सेस नियंत्रण जोड़ा जाएगा।
- views
- यह टैग Views मॉड्यूल द्वारा बनाई गई क्वेरीज़ के लिए उपयोग होता है।
Meta data (मेटा डेटा)
क्वेरीज़ के साथ अतिरिक्त जानकारी जोड़ने के लिए मेटा डेटा का उपयोग किया जा सकता है। मेटा डेटा एक सामान्य PHP वेरिएबल होती है, जो किसी कुंजी (string key) के साथ स्टोर की जाती है। यह डेवलपर्स को क्वेरी संशोधन (alter) के दौरान अधिक संदर्भ प्रदान करती है।
<?php $node = node_load($nid); // ... यहाँ $query ऑब्जेक्ट बनाएँ। $query->addMetaData('node', $node); ?>
मेटा डेटा स्वयं क्वेरी की संरचना को प्रभावित नहीं करता, बल्कि यह केवल अतिरिक्त जानकारी उपलब्ध कराता है ताकि hook_query_alter() के दौरान उसका उपयोग किया जा सके। मेटा डेटा को प्राप्त करने के लिए getMetaData() मेथड का उपयोग करें:
<?php $node = $query->getMetaData('node'); ?>
यदि निर्दिष्ट कुंजी के साथ कोई मेटा डेटा मौजूद नहीं है, तो यह NULL लौटाता है।
hook_query_alter()
टैग्स और मेटा डेटा केवल जानकारी प्रदान करते हैं — वे स्वयं क्वेरी को नहीं बदलते। असल परिवर्तन hook_query_alter() के माध्यम से किए जाते हैं, जो कि किसी भी डायनेमिक SELECT क्वेरी ऑब्जेक्ट पर कार्य कर सकता है।
सभी डायनेमिक क्वेरीज़ को execute() से ठीक पहले (यानी संकलित होने से पहले) hook_query_alter() के माध्यम से पास किया जाता है। इस चरण पर मॉड्यूल्स क्वेरी को किसी भी तरह संशोधित कर सकते हैं। यह हुक एक पैरामीटर स्वीकार करता है — QueryAlterableInterface प्रकार का ऑब्जेक्ट:
<?php /** * hook_query_alter() का उदाहरण। */ function example_query_alter(QueryAlterableInterface $query) { // यहाँ क्वेरी संशोधित करें। } ?>
यदि आप केवल किसी विशिष्ट टैग की क्वेरी को संशोधित करना चाहते हैं, तो आप विशेष हुक hook_query_TAGNAME_alter() का उपयोग कर सकते हैं। उदाहरण के लिए, यदि क्वेरी में “node_access” टैग है:
<?php function example_query_node_access_alter(QueryAlterableInterface $query) { // केवल “node_access” टैग वाली क्वेरीज़ को संशोधित करें। } ?>
महत्वपूर्ण बातें:
- $query पैरामीटर को रेफ़रेंस द्वारा पास करने की आवश्यकता नहीं है। चूँकि यह एक ऑब्जेक्ट है, PHP 5 में यह स्वतः रेफ़रेंस के रूप में ही कार्य करता है। हुक को कोई वैल्यू रिटर्न करने की आवश्यकता नहीं है।
- पैरामीटर का प्रकार स्पष्ट रूप से QueryAlterableInterface बताया गया है — इससे गलत प्रकार के ऑब्जेक्ट पास होने से सुरक्षा मिलती है। इसे भविष्य में SelectQuery और अन्य प्रकार की क्वेरीज़ के साथ भी संगतता के लिए परिभाषित किया गया है।
hook_query_alter() क्वेरी ऑब्जेक्ट में किसी भी तरह का परिवर्तन कर सकता है — जैसे फ़ील्ड जोड़ना, शर्तें बदलना, जोइन जोड़ना आदि — बशर्ते कि यह क्वेरी को पुनः निष्पादित (execute) न करे, अन्यथा यह अनंत लूप पैदा कर सकता है।
यह हुक टैग्स और मेटा डेटा का उपयोग यह निर्धारित करने के लिए कर सकता है कि किस स्थिति में कौन-सा संशोधन लागू करना है। उदाहरण के लिए, मॉड्यूल डेवलपर्स क्वेरी में फ़ील्ड्स, जोइन, कंडीशन्स, ऑर्डरिंग आदि जोड़ या हटा सकते हैं।
क्वेरी के आंतरिक भागों तक पहुँचने के लिए, आप निम्नलिखित मेथड्स का उपयोग कर सकते हैं — ये सभी रेफ़रेंस द्वारा डेटा लौटाते हैं:
<?php $fields =& $query->getFields(); $expressions =& $query->getExpressions(); $tables =& $query->getTables(); $order =& $query->getOrderBy(); $where =& $query->conditions(); $having =& $query->havingConditions(); ?>
ध्यान दें कि ये सभी वैरिएबल्स रेफ़रेंस द्वारा लौटाए जाते हैं, ताकि hook के अंदर किए गए किसी भी परिवर्तन सीधे मूल क्वेरी पर लागू हों। इन सभी मेथड्स के परिणाम ऐरे (arrays) के रूप में होते हैं, और उनकी संरचना includes/database/select.inc फ़ाइल में SelectQuery क्लास की डॉक्युमेंटेशन में वर्णित है।