9.11.3. एंटिटी हुक्स (Entity Hooks)
पिछले लेखों में हम पहले ही hooks से परिचित हो चुके हैं। इस लेख में, हम उन हुक्स को विस्तार से देखेंगे जो एंटिटीज़ (Entities) के साथ काम करने में मदद करते हैं।
सामान्य रूप से यह जानने के लिए कि हुक्स क्या होते हैं और उनकी आवश्यकता क्यों होती है, आप इस लेख को पढ़ सकते हैं:
http://drupalbook.org/drupal/92-what-hook-drupal-8
हम हुक्स का उपयोग अपने कस्टम कोड को जोड़ने के लिए करेंगे, जो एंटिटीज़ से संबंधित कुछ विशेष घटनाओं पर चलेंगे — जैसे जोड़ना (add), हटाना (delete), अपडेट करना (update)।
आप सभी Drupal हुक्स की सूची इस पेज पर देख सकते हैं:
https://api.drupal.org/api/drupal/core!core.api.php/group/hooks/8.2.x
हम केवल उन्हीं हुक्स पर ध्यान देंगे जो प्रायः कंटेंट के साथ काम करने वाले कस्टम मॉड्यूल्स में सबसे अधिक उपयोग किए जाते हैं।
मैंने सारा कोड GitHub पर drupalbook_examples मॉड्यूल में जोड़ा है। आप इस मॉड्यूल को डाउनलोड करके अपनी वेबसाइट पर जोड़ सकते हैं:
https://github.com/levmyshkin/drupalbook8
hook_entity_presave()
/**
* Implements hook_entity_presave().
*/
function drupalbook_examples_entity_presave(Drupal\Core\Entity\EntityInterface $entity) {
if ($entity->getEntityTypeId() == 'node' && $entity->getType() == 'article') {
$entity->title->value = $entity->title->value . ' by ' . date('d-m-Y');
}
}
hook_entity_presave()
हर बार किसी एंटिटी को सेव करने से पहले चलाया जाता है।
इस हुक के अंदर $entity->save()
को कॉल करने की आवश्यकता नहीं है, क्योंकि एंटिटी ऑब्जेक्ट को सेव करने से पहले ही बदला जा सकता है। इस उदाहरण में, हम लेख (article) के शीर्षक में सेव की गई तारीख जोड़ते हैं। यदि अगले दिन आप लेख को फिर से अपडेट करेंगे, तो नई तारीख फिर से जुड़ जाएगी। इसलिए सेव करने से पहले शीर्षक में जोड़ी गई तारीख को हटाना ज़रूरी है, अन्यथा हर सेव पर शीर्षक और लंबा होता जाएगा।
आम तौर पर इस हुक का उपयोग एंटिटी को सेव करते समय फ़ील्ड्स के मान की जांच करने या किसी बदलाव की सूचना ईमेल के माध्यम से भेजने के लिए किया जाता है।
ध्यान दें कि हम पहले एंटिटी के प्रकार की जाँच करते हैं, क्योंकि यह हुक सभी एंटिटीज़ (कंटेंट, ब्लॉक्स, कमेंट्स, टैक्सोनॉमी टर्म्स) पर चलता है। इसके साथ ही हमें वांछित बंडल (bundle) की भी जाँच करनी चाहिए।
hook_entity_insert()
/**
* Implements hook_entity_insert().
*/
function drupalbook_examples_entity_insert(Drupal\Core\Entity\EntityInterface $entity) {
if ($entity->getEntityTypeId() == 'node' && $entity->getType() == 'page') {
$node = Node::create([
'type' => 'article',
'title' => 'New page created: ' . $entity->title->value,
]);
$node->save();
}
}
hook_entity_insert()
तब चलता है जब कोई नई एंटिटी जोड़ी जाती है। उदाहरण के लिए, जब साइट पर एक नया पेज बनाया जाता है, तो स्वचालित रूप से एक नया लेख (article) भी बनाया जाएगा। यदि आपने पहले वाला हुक भी लिखा है, तो लेख के शीर्षक में तारीख भी जुड़ जाएगी।
यह ध्यान देना महत्वपूर्ण है कि hook_entity_insert()
और hook_entity_presave()
में अंतर है। hook_entity_insert()
केवल एक बार चलता है — जब एंटिटी पहली बार जोड़ी जाती है — और यह एंटिटी के फ़ील्ड मानों को नहीं बदलता।
/**
* Implements hook_entity_insert().
*/
function drupalbook_examples_entity_insert(Drupal\Core\Entity\EntityInterface $entity) {
if ($entity->getEntityTypeId() == 'node' && $entity->getType() == 'article') {
$entity->title->value = $entity->title->value . ' by ' . date('d-m-Y');
}
}
हालाँकि, आप एंटिटी को सेव करवाने का तरीका जोड़ सकते हैं, लेकिन ऐसा करना अनुशंसित नहीं है:
function your_module_entity_insert(Drupal\Core\Entity\EntityInterface $entity){
if ($entity->getType() == 'article') {
drupal_register_shutdown_function('_your_module_post_insert', $entity);
}
}
function _your_module_entity_insert(Drupal\Core\Entity\EntityInterface $entity) {
if ($entity) {
$entity->save();
}
}
ऐसा करना उचित नहीं है। सबसे अच्छा तरीका यह है कि एंटिटी में बदलाव करने के लिए hook_entity_presave() का उपयोग करें और अन्य क्रियाएँ (जैसे नई एंटिटी बनाना या लॉगिंग करना) के लिए hook_entity_insert() का।
hook_entity_update()
/**
* Implements hook_entity_update().
*/
function drupalbook_examples_entity_update(Drupal\Core\Entity\EntityInterface $entity) {
if ($entity->getEntityTypeId() == 'node' && $entity->getType() == 'page') {
\Drupal::messenger()->addMessage('Page has been changed: ' . $entity->title->value);
}
}
hook_entity_update()
हर बार एंटिटी अपडेट होने पर चलता है। लेकिन इस हुक के अंदर भी एंटिटी के फ़ील्ड्स को सीधे बदलना नहीं चाहिए, क्योंकि यह केवल बाहरी क्रियाएँ करने के लिए होता है — जैसे लॉगिंग, नोटिफिकेशन भेजना आदि।
$entity->save()
को इस हुक में दोबारा कॉल न करें, वरना यह हुक फिर से ट्रिगर होगा और एक लूप बन जाएगा।
hook_entity_delete()
यह हुक एंटिटी के हटाए जाने के बाद चलता है। इसका उपयोग लॉगिंग या सफाई (cleanup) कार्यों को करने के लिए किया जा सकता है।
hook_entity_access()
<?php
use Drupal\Core\Access\AccessResult;
/**
* Implements hook_entity_access().
*/
function drupalbook_examples_entity_access(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Session\AccountInterface $account) {
if ($entity->getEntityTypeId() == 'node' && $entity->getType() == 'article' && $operation == 'view' && in_array('administrator', $account->getRoles())) {
AccessResult::forbidden();
}
}
?>
इस उदाहरण में, हम उन सभी उपयोगकर्ताओं के लिए लेखों (articles) तक पहुँच को ब्लॉक कर रहे हैं जिनके पास administrator भूमिका नहीं है।
यदि आपके लिए मानक भूमिकाओं और अनुमतियों (permissions) का उपयोग पर्याप्त है, तो इन्हें Drupal UI से कॉन्फ़िगर करना बेहतर है। लेकिन यदि आपको विशेष स्थितियों में एक्सेस को सीमित करना है — जैसे समय-सारणी (schedule), userpoints, karma या उपयोगकर्ता स्तरों (user levels) के अनुसार — तो hook_entity_access() उपयोगी होता है।
हालाँकि, यदि आप मानक एक्सेस कंट्रोल को ओवरराइड करते हैं, तो यह अन्य डेवलपर्स के लिए भ्रम पैदा कर सकता है, क्योंकि यह स्पष्ट नहीं होगा कि यह व्यवहार किसी हुक के कारण हो रहा है। यही हुक्स का एक प्रमुख नकारात्मक पहलू है — तृतीय-पक्ष कोड का छिपा हुआ निष्पादन।
इसलिए यदि किसी प्रोजेक्ट में अचानक लेखों के शीर्षक बदलते नज़र आते हैं या नोड सेव करते समय कुछ असामान्य होता है, तो आपको पूरे प्रोजेक्ट में entity_presave या entity_update जैसे हुक्स को खोजने की आवश्यकता होगी।
हमने यहाँ कुछ प्रमुख हुक्स का विश्लेषण किया है, और अब आपको यह स्पष्ट हो जाना चाहिए कि इन्हें कहाँ और कब उपयोग करना चाहिए। जैसे-जैसे आप Drupal विकास में आगे बढ़ेंगे, आपको कस्टम कोड लिखने की आवश्यकता अधिक बार महसूस होगी — और ये हुक्स आपके लिए सही जगह पर कोड जोड़ने का उत्कृष्ट तरीका साबित होंगे।