9.10. Drupal Fields API. Drupal polja u bazi podataka.
U ovom članku ćemo razumeti kako polja u Drupalu funkcionišu, zašto su potrebna i kako polja pomažu da se brzo razvijaju sajtovi u Drupalu.
Već smo radili sa poljima u prethodnim člancima:
7.5. Kreiranje bloka usluga sa bootstrap kolonama
7.6. Isotope galerija za Drupal
7.7. Blok sa YouTube videom u Drupalu
Sada ćemo razjasniti kako to funkcioniše. Idemo na uređivanje polja tipa sadržaja Članak i dodajmo novo polje tipa Link:
/admin/structure/types/manage/article/fields
Kada kreirate novi članak, imaćete dva polja za unos URL-a i teksta linka:
Svaki put kada kreirate novo polje preko administracije, u bazi se kreiraju dve tabele:
{entity_type}__{field_name}
{entity_type}_revision__{field_name}
Drupal podržava revizije, pa će se svi podaci duplirati barem jednom, jer je jedina revizija aktuelna verzija vašeg članka. Dakle, polja i celokupni Drupal Fields API služe da pojednostave rad sa bazom. Jednostavno kreiramo polja preko administracije, a Drupal već kreira tabele u bazi podataka.
Iz naziva MySQL tabela treba biti jasno da isto polje može da se koristi za jedan tip entiteta. Na primer, sada možemo koristiti polje Link u sadržaju tipa osnovna stranica kao već postojeće:
/admin/structure/types/manage/page/fields/add-field
Ali ako želite da kreirate Link polje u bloku, moraćete da napravite novo polje. Nije moguće koristiti isto polje u entitetima različitih tipova. Napravićemo Link polje za tip osnovnog bloka:
/admin/structure/block/block-content/manage/basic/fields/add-field
Kao što vidite, prilikom kreiranja polja nema izbora postojećeg Link polja, jer su Blok i Nod različiti tipovi entiteta.
I kao što je za nodove, imaćemo dve tabele za skladištenje podataka Link polja za blokove:
block_content_revision__field_link и block_content__field_link.
Sada da razumemo kako Drupal čuva podatke istog polja za različite bundlove nodova. Napravili smo Link polje za tip nod Članak, ali smo zatim ponovo koristili to polje za osnovnu stranicu. Za praktičnost je najbolje da se konfiguracija sajta skine u folder i vidi fajlove, ali konfiguraciju možete pronaći i preko adminera ili phpmyadmin-a u tabeli config:
Ako pretražite sve konfiguracije koje sadrže reč link:
SELECT * FROM `config` WHERE CONVERT(`name` USING utf8mb4) LIKE '%link%' LIMIT 50
Pronaći ćemo sledeće konfiguracije za naše field_link polje:
field.field.block.block_content.basic.field_link
field.field.node.article.field_link
field.field.node.page.field_link
field.storage.block_content.field_link
field.storage.node.field_link
Za svaki tip entiteta, za svako polje kreira se posebna konfiguracija Field Storage. Ova konfiguracija odgovara na to kako se čuvaju podaci u tabelama {entity_type}__{field_name}, {entity_type}_revision__{field_name}. U našem slučaju to su tabele block_content__field_link, block_content_revision__field_link, node__field_link, node_revision__field_link. Dalje ćemo pogledati kako Link modul skladišti podatke. Otvorimo konfiguraciju Field Storage za Link polje:
uuid: dba847ef-f4d6-4462-a2ee-f642a007fca6 langcode: en status: true dependencies: module: - block_content - link id: block_content.field_link field_name: field_link entity_type: block_content type: link settings: { } module: link locked: false cardinality: 1 translatable: true indexes: { } persist_with_no_fields: false custom_storage: false
Pogledajmo svaku od ovih stavki da bude jasno šta se tačno čuva u konfiguraciji Field Storage.
uuid: dba847ef-f4d6-4462-a2ee-f642a007fca6
Ovo je jedinstveni ID konfiguracije. Nema potrebe da polje kreirate ručno na produkciji ako ste ga kreirali lokalno i uvezli konfiguraciju. Polje će biti automatski kreirano. Ako izbrišete polje i obrišete konfiguraciju lokalno, nakon uvoza na produkciju podaci će biti obrisani. Zato ako polje kreirate na produkciji, izvezite konfiguraciju i ubacite je u git da ne izgubite promene.
langcode: en
Na sajtovima sa više jezika za različite verzije nodova za različite jezike u tabeli polja se čuvaju svi podaci sa oznakom jezika kojoj pripadaju:
Imam isti jezik, pa je podrazumevani jezik u konfiguraciji isti.
status: true
Opšte polje konfiguracionih entiteta koje pokazuje da li je entitet uključen ili isključen. Konfiguracioni entitet Field Storage koristi klasu FieldStorageConfig koja je izvedena iz ConfigEntityBase:
https://api.drupal.org/api/drupal/core!modules!field!src!Entity!FieldStorageConfig.php
dependencies: module: - block_content - link
Zavisnosti od dodatnih modula. Pošto koristimo Link polje u blokovima, potrebna je obavezno modul Block content.
id: block_content.field_link
Jedinstveni naziv naše konfiguracije.
field_name: field_link
Mašinski naziv polja koji koristi Drupal, na primer za pristup objektu nod $node->field_link->uri. Kako se referiše na polje entiteta videćemo detaljnije u narednim člancima.
entity_type: block_content
Tip entiteta za koji je ovo polje konfigurisano.
type: link
Tip polja u Drupalu. Možete praviti i svoje tipove polja, ali sada je bitno da znate da je ovaj link polje kreirao Link modul. Pogledajte klasu:
core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
koja se koristi za ovu funkcionalnost.
settings: { }
Ovde se čuvaju podešavanja za tip polja, trenutno prazna, ali na primer za polje body postoji podešavanje za prikaz teasera ili ne:
config/sync/field.field.block_content.basic.body.yml
settings:
display_summary: false
module: link
Modul koji implementira tip polja link. Ime modula i tip polja mogu biti različiti, na primer modul DateTime ima više tipova polja:
core/modules/datetime/src/Plugin/Field/FieldType/DateTimeFieldItemList.php
core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php
locked: false
Da li je polje dostupno za uređivanje podešavanja. Na primer, polja u Commerce modulu su nekada bila zaključana jer su bila obavezna za obračun dostave i poreza.
cardinality: 1
Broj vrednosti koje se mogu uneti za jedno polje entiteta. Ovde je izabrano jedno, ali može biti i više, ili neograničeno (-1).
translatable: true
Da li je polje prevedivo na druge jezike.
indexes: { }
Dodatni SQL indeksi za optimizaciju pretrage u polju.
persist_with_no_fields: false
Da li da se čuvaju podaci čak i ako su polja uklonjena iz svih entiteta.
custom_storage: false
Da li se koristi prilagođena tabela za skladištenje podataka umesto standardnih {entity_type}__{field_name} tabela. Ovo se koristi za specijalne integracije.
Sada ćemo otvoriti fajl tipa polja link:
core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
i videti koje podatke ovo polje čuva u bazi, što se vidi u metodu propertyDefinitions():
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) { $properties['uri'] = DataDefinition::create('uri') ->setLabel(t('URI')); $properties['title'] = DataDefinition::create('string') ->setLabel(t('Link text')); $properties['options'] = MapDataDefinition::create() ->setLabel(t('Options')); return $properties; }
Kao što vidite, čuvamo URI, naslov i opcije. Ako otvorite tabelu node__field_link, videćete iste kolone:
Sada smo stigli do teme Fields API u Drupalu. Kreiramo tip polja preko modula u PHP fajlu sa klasom LinkItem. Ovo nam omogućava da napravimo polje za entitet, a zatim da koristimo to polje za unos i skladištenje podataka u bazi. Ovo je deo za unos podataka. Fields API takođe konfiguriše formu za unos podataka i prikaz naših polja.
Vratimo se na moment kada smo kreirali polja za tipove sadržaja Članak i Osnovna stranica. Imamo jednu konfiguraciju Field Storage za nod: field.storage.node.field_link.yml, ali pri kreiranju polja kreira se još jedna konfiguracija za svaki bundle u entitetu, pa sada imamo tri konfiguracije za polje:
field.field.node.article.field_link.yml
field.field.node.page.field_link.yml
field.field.block.block_content.basic.field_link.yml
Ove konfiguracije čuvaju podešavanja sa forme za polje:
Na ovaj način možemo različito konfigurisati formu za unos polja za različite bundlove. Svaka konfiguracija polja u bundlu zove se Field Instance u Drupalu, tako da prvo kreiramo Field Storage, koje se može koristiti za Field Instance zasebno u svakom bundlu. U Drupalu 8, za razliku od 7, nema više funkcija za rad sa Field Instances, već je funkcionalnost prebačena u CRUD API:
https://www.drupal.org/node/2054619
Primere rada sa poljima kroz kod možete videti u zvaničnoj dokumentaciji:
https://www.drupal.org/node/2012896
Pregledali smo samo deo Fields API koji se tiče skladištenja podataka polja u bazi. U narednim lekcijama ćemo proučiti kako Fields API radi sa unosom podataka i prikazom polja, kao i napraviti svoj kompletan tip polja.