कस्टम कंटेंट बनाना
दर्शक वर्ग
यह दस्तावेज़ मुख्य रूप से उन डेवलपर्स के लिए है, जिन्हें ऑब्जेक्ट-ओरिएंटेड PHP, Drupal 6 या Drupal 7 का अनुभव है, और जो Drupal 8 के सिद्धांतों को सीखना चाहते हैं।
Drupal 8 में कंटेंट एंटिटी टाइप बनाने का दस्तावेज़ उपलब्ध विकल्पों की पूरी सूची शामिल करता है।
Drupal 8 में बिना बंडल के कंटेंट टाइप बनाना
इस मामले में हम Drupal 8 का कंटेंट एंटिटी ऑब्जेक्ट बना रहे हैं, जिसके पास कोई बंडल नहीं है।
एंटिटी Field API को लागू नहीं करती, इसलिए यह कोड में रहती है। फिर भी, यह Content Entities बनाने के लिए उपयोगी ढांचा हो सकता है, क्योंकि हम बाद में अधिक जटिल डेटा इम्पोर्ट करेंगे।
अंततः, जहाँ भी कुछ OOP अवधारणाएँ होंगी, मैं संबंधित दस्तावेज़ों का संदर्भ दूँगा।
पृष्ठभूमि
हमारा मॉड्यूल advertiser कहलाता है।
हमारी कंटेंट एंटिटी टाइप का नाम भी advertiser है।
हमारी नई Drupal 8 advertiser कंटेंट एंटिटी के पास ये फ़ील्ड्स होंगी:
- UUID
- ID
Drupal 8 में कंटेंट ऑब्जेक्ट को परिभाषित करना
सबसे पहले, अब सभी कस्टम ऑब्जेक्ट्स modules/custom में रहते हैं, न कि sites/all/modules/custom में।
हमारे कस्टम ऑब्जेक्ट की फ़ाइल संरचना इस प्रकार होगी:
modules/custom/advertiser$
├── advertiser.info.yml
└── src
└── Entity
└── Advertiser.php
संदर्भ के लिए आप तैयार Advertiser एंटिटी देख सकते हैं, जिसमें टेस्ट और constraint plugins जैसे अतिरिक्त जोड़ शामिल हैं, लेकिन फिलहाल हम सरल रूप से शुरू करेंगे।
Info फ़ाइल
हम अपने कस्टम मॉड्यूल को module_name.info.yml में परिभाषित करना शुरू करेंगे:
name: Advertiser type: module description: 'Barebones advertiser entity' package: custom core: 8.x
एंटिटी स्केलेटन
Advertiser एंटिटी का बेस क्लास और स्कीमा src/Entity/Advertiser.php में परिभाषित है।
सबसे पहले हम namespace को परिभाषित करते हैं:
namespace Drupal\advertiser\Entity;
अब समय है अपनी एंटिटी को परिभाषित करने का, जिसे हम annotation में करते हैं।
यह वास्तव में ऑब्जेक्ट टाइप को परिभाषित करता है जिसे Drupal पढ़ता और cache करता है, इसलिए हर बदलाव के बाद cache साफ़ करना न भूलें।
<?php
/**
* Advertiser entity को परिभाषित करता है।
*
* @ingroup advertiser
*
* @ContentEntityType(
* id = "advertiser",
* label = @Translation("Advertiser"),
* base_table = "advertiser",
* entity_keys = {
* "id" = "id",
* "uuid" = "uuid",
* },
* )
*/
?>
चूँकि यह एक खाली एंटिटी है, हम केवल कुछ properties का उपयोग कर रहे हैं और Access जैसे हैंडलर्स शामिल नहीं कर रहे।
हमारे पास अब एक functional मॉड्यूल है जो हमारी कस्टम कंटेंट एंटिटी को परिभाषित करता है, लेकिन अभी डेटाबेस में "advertiser" टेबल नहीं बनी है:
$ drush sql-cli mysql> SHOW TABLES;
यह इसलिए क्योंकि हमारे क्लास में ऐसे methods नहीं हैं जो सीधे डेटाबेस से इंटरैक्ट करें। हमें न्यूनतम आवश्यक methods को परिभाषित करना होगा।
ContentEntityBase
आमतौर पर हम use Drupal\Core\Entity\ContentEntityBase; जोड़ते हैं। इससे हमें ऐसे methods मिलते हैं जिन्हें हम अपने क्लास में extend कर सकते हैं।
हम दो काम करते हैं: ContentEntityBase को extend करना और ContentEntityInterface को implement करना।
यह methods को परिभाषित करता है जिन्हें हमें DB तक पहुँचने के लिए चाहिए। यह यह नहीं बताता कि हम इसे कैसे हासिल करते हैं। यह implementing class का काम है।
तो हमें यह मिलता है:
class Advertiser extends ContentEntityBase implements ContentEntityInterface {
अब हम base fields जोड़ सकते हैं।
baseFieldDefinitions
यह method FieldableEntityInterface से आता है और base fields को परिभाषित करता है।
<?php
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
// Standard field, used as unique if primary index.
$fields['id'] = BaseFieldDefinition::create('integer')
->setLabel(t('ID'))
->setDescription(t('The ID of the Advertiser entity.'))
->setReadOnly(TRUE);
// Standard field, unique outside of the scope of the current project.
$fields['uuid'] = BaseFieldDefinition::create('uuid')
->setLabel(t('UUID'))
->setDescription(t('The UUID of the Advertiser entity.'))
->setReadOnly(TRUE);
return $fields;
}
?>
BaseFieldDefinition का उपयोग field बनाने और constraints जोड़ने के लिए किया जाता है।
पूर्ण एंटिटी
तो अंतिम कोड इस प्रकार है:
<?php
namespace Drupal\advertiser\Entity;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\ContentEntityInterface;
/**
* Defines the advertiser entity.
*
* @ingroup advertiser
*
* @ContentEntityType(
* id = "advertiser",
* label = @Translation("advertiser"),
* base_table = "advertiser",
* entity_keys = {
* "id" = "id",
* "uuid" = "uuid",
* },
* )
*/
class Advertiser extends ContentEntityBase implements ContentEntityInterface {
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
// Standard field, used as unique if primary index.
$fields['id'] = BaseFieldDefinition::create('integer')
->setLabel(t('ID'))
->setDescription(t('The ID of the Advertiser entity.'))
->setReadOnly(TRUE);
// Standard field, unique outside of the scope of the current project.
$fields['uuid'] = BaseFieldDefinition::create('uuid')
->setLabel(t('UUID'))
->setDescription(t('The UUID of the Advertiser entity.'))
->setReadOnly(TRUE);
return $fields;
}
}
?>
मॉड्यूल इंस्टॉल करने के बाद अब आप देखेंगे कि डेटाबेस में "advertiser" टेबल बन गई है!
$ drush sql-cli mysql> SHOW TABLES;
या:
drush sqlq "show tables like 'advertiser'" drush sqlq "describe advertiser"
अगर मॉड्यूल पहले से इंस्टॉल है, तो आपको entity update चलाना होगा।
देखें: #2976035: CRUD operations with entity type should use latest installed definitions और संबंधित change record।
इसके लिए आप Devel Entity Updates मॉड्यूल का उपयोग कर सकते हैं।