Definisanje i korišćenje definicija Content Entity Field
Content entiteti moraju eksplicitno definisati svoja polja pružajući definicije u okviru klase entiteta. Definicije polja su bazirane na Typed data API-ju (pogledajte kako ga entiteti implementiraju).
Definicije polja
Tipovi entiteta definišu svoja osnovna polja u statičkoj metodi klase entiteta. Osnovna polja su podešena polja koja uvek postoje za dati tip entiteta, kao što su naslov čvora ili datumi kreiranja i izmene. Menadžer entiteta dopunjava polja podesivim i nepodesivim poljima koja pružaju drugi moduli pozivajući hook_entity_field_info() i hook_entity_field_info_alter(). Takođe, polja konfigurisana kroz Field UI se dodaju na ovaj način (ovi hookovi više ne postoje prema API-ju).
Definicije polja su jednostavni objekti koji implementiraju FieldDefinitionInterface, dok osnovna polja obično kreira klasa BaseFieldDefinition, a podesiva polja direktno implementiraju interfejs kroz odgovarajuće konfiguracione objekte (Field i FieldInstance).
Definicije polja su takođe mesto za definisanje validacionih ograničenja za polje ili njegova svojstva. Mogu se koristiti sve implementacije plugina tipa polja. (Ovaj interfejs i klasa više ne postoje).
Polja su uvek lista field item objekata, što znači da je klasa FieldItem definisana kao tip unutar klase FieldItemList koja predstavlja listu tih polja.
Sva polja (uključujući osnovna) mogu imati vidžete i formatere za prikaz i uređivanje.
Osnovna polja
Ispod je skraćeni primer definicija polja za entitet tipa čvora (node).
use Drupal\Core\Field\BaseFieldDefinition; class Node implements NodeInterface { /** * {@inheritdoc} */ public static function baseFieldDefinitions($entity_type) { // ID čvora je integer, koristi IntegerItem tip polja. $fields['nid'] = BaseFieldDefinition::create('integer') ->setLabel(t('Node ID')) ->setDescription(t('The node ID.')) ->setReadOnly(TRUE); // UUID polje koristi tip uuid_field koji automatski generiše novi UUID prilikom kreiranja entiteta. $fields['uuid'] = BaseFieldDefinition::create('uuid') ->setLabel(t('UUID')) ->setDescription(t('The node UUID.')) ->setReadOnly(TRUE); // Jezički kod je definisan kao language_field koji osigurava validan podrazumevani jezik za nove entitete. $fields['langcode'] = BaseFieldDefinition::create('language') ->setLabel(t('Language code')) ->setDescription(t('The node language code.')); // Naslov je StringItem, sa podrazumevanom praznom vrednošću i ograničenjem na najviše 255 karaktera. $fields['title'] = BaseFieldDefinition::create('string') ->setLabel(t('Title')) ->setDescription(t('The title of this node, always treated as non-markup plain text.')) ->setRequired(TRUE) ->setTranslatable(TRUE) ->setSettings(array( 'default_value' => '', 'max_length' => 255, )); // uid je entity_reference na korisnika, omogućava pristup korisničkom ID sa $node->uid->target_id // i korisničkom entitetu sa $node->uid->entity. NodeInterface definiše i getAuthor() i getAuthorId(). $fields['uid'] = BaseFieldDefinition::create('entity_reference') ->setLabel(t('User ID')) ->setDescription(t('The user ID of the node author.')) ->setSettings(array( 'target_type' => 'user', 'default_value' => 0, )); // Changed polje automatski ažurira timestamp svaki put kad se entitet sačuva. $fields['changed'] = BaseFieldDefinition::create('changed') ->setLabel(t('Changed')) ->setDescription(t('The time that the node was last edited.')); return $fields; } }
Polja sa više vrednosti
Da biste postavili maksimalan broj elemenata dozvoljenih za polje, pozovite metod setCardinality().
Na primer, da definišete polje koje može imati najviše 3 elementa:
->setCardinality(3);
Da definišete polje sa neograničenim brojem vrednosti, pozovite:
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
Primer definicije polja sa više vrednosti koje referencira entitete tipa „user“:
$fields['my_field'] = BaseFieldDefinition::create('entity_reference') ->setLabel(t('The label of the field')) ->setDescription(t('The description of the field.')) ->setRevisionable(TRUE) ->setSetting('target_type', 'user') ->setSetting('handler', 'default') ->setTranslatable(TRUE) ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'author', 'weight' => 0, ]) ->setDisplayOptions('form', [ 'type' => 'entity_reference_autocomplete', 'weight' => 5, 'settings' => [ 'match_operator' => 'CONTAINS', 'size' => '60', 'autocomplete_type' => 'tags', 'placeholder' => '', ], ]) ->setDisplayConfigurable('form', TRUE) ->setDisplayConfigurable('view', TRUE) ->setRequired(TRUE) ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
Entitet može imati polja koja postoje samo za određeni bundle ili mogu biti izmenjena po bundle-u. Na primer, naslov čvora može imati različitu oznaku za svaki bundle. Da bi se omogućile izmene po bundle-u, definicija osnovnog polja mora biti klonirana pre izmene, jer bi u suprotnom promenila osnovnu definiciju za sve bundle-ove.
use Drupal\node\Entity\NodeType; /** * {@inheritdoc} */ public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) { $node_type = NodeType::load($bundle); $fields = array(); if (isset($node_type->title_label)) { $fields['title'] = clone $base_field_definitions['title']; $fields['title']->setLabel($node_type->title_label); } return $fields; }
Tipovi polja
Drupal core pruža listu tipova polja koje se mogu koristiti za osnovna polja. Pored toga, moduli mogu pružati dodatne tipove polja.
- string: jednostavan tekstualni string
- boolean: logička vrednost, skladištena kao ceo broj
- integer: ceo broj sa proverama minimalne i maksimalne vrednosti (dostupni su i decimalni i floating point tipovi)
- decimal: decimalni broj sa podesivom preciznošću i skalom
- float: broj sa pokretnim zarezom
- language: sadrži kod jezika i jezik kao izračunatu osobinu
- timestamp: unix timestamp, skladišten kao ceo broj
- created: timestamp koji po defaultu koristi vreme kreiranja
- changed: timestamp koji se automatski ažurira prilikom čuvanja entiteta
- datetime: datum u ISO 8601 formatu
- uri: sadrži URI. Modul Link pruža tip polja link koji može uključivati naslov i može pokazivati na unutrašnji ili spoljni URI/rutu.
- uuid: UUID polje koje automatski generiše novi UUID po defaultu
- email: email sa validacijom, vidžetima i formatterima
- entity_reference: referenca na entitet preko target_id i polja computed entity. Modul entity_reference pruža vidžete i formattere kada je omogućen.
- map: može sadržati proizvoljan broj svojstava skladištenih kao serijalizovani string
Podesiva polja
Dodatna polja se mogu registrovati preko hook_entity_base_field_info() i hook_entity_bundle_field_info(). U sledećim primerima dodaju se osnovna i bundle polja.
use Drupal\Core\Field\BaseFieldDefinition; /** * Implements hook_entity_base_field_info(). */ function path_entity_base_field_info(EntityTypeInterface $entity_type) { if ($entity_type->id() === 'taxonomy_term' || $entity_type->id() === 'node') { $fields['path'] = BaseFieldDefinition::create('path') ->setLabel(t('The path alias')) ->setComputed(TRUE); return $fields; } } /** * Implements hook_entity_bundle_field_info(). */ function field_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) { if ($entity_type->isFieldable()) { // Podesiva polja koja su uvek vezana za određeni bundle se dodaju 'po bundle-u'. return Field::fieldInfo()->getBundleInstances($entity_type->id(), $bundle); } }
Odgovarajući alter hookovi postoje za oba gore navedena hooka.
Skladištenje polja
Ako polje nema posebne zahteve, API Entity Field može sam da se pobrine za skladištenje u bazi i da ažurira šeme baze. Ovo je podrazumevano ponašanje za polja koja nisu označena kao izračunata (setComputed(TRUE)) ili koja nemaju sopstveno skladište (setCustomStorage(TRUE)).
Recimo da želite da dodate novo osnovno polje za sve Node entitete koje sadrži jednostavnu boolean vrednost koja označava da li je sadržaj istaknut.
use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; /** * Implements hook_entity_base_field_info(). */ function MYMODULE_entity_base_field_info(EntityTypeInterface $entity_type) { $fields = array(); // Dodaje 'Highlight' osnovno polje za sve čvorove. if ($entity_type->id() === 'node') { $fields['highlight'] = BaseFieldDefinition::create('boolean') ->setLabel(t('Highlight')) ->setDescription(t('Whether or not the node is highlighted.')) ->setRevisionable(TRUE) ->setTranslatable(TRUE) ->setDisplayOptions('form', array( 'type' => 'boolean_checkbox', 'settings' => array( 'display_label' => TRUE, ), )) ->setDisplayConfigurable('form', TRUE); } return $fields; }
Često, pokretanje update.php neće automatski dodati kolonu u bazu podataka, ali sledeći kod može pokrenuti kreiranje kolone:
\Drupal::entityTypeManager()->clearCachedDefinitions(); \Drupal::service('entity.definition_update_manager')->applyUpdates();
Napomena: ovo će takođe pokrenuti sva druga ažuriranja koja čekaju za druga polja.
Napomena: gornji kod neće raditi sa Drupal 8.7
Za više informacija pogledajte ovu promenu.
Instalacija nove definicije skladištenja polja
function example_update_8701() { $field_storage_definition = BaseFieldDefinition::create('boolean') ->setLabel(t('Revision translation affected')) ->setDescription(t('Indicates if the last edit of a translation belongs to current revision.')) ->setReadOnly(TRUE) ->setRevisionable(TRUE) ->setTranslatable(TRUE); \Drupal::entityDefinitionUpdateManager() ->installFieldStorageDefinition('revision_translation_affected', 'block_content', 'block_content', $field_storage_definition); }
Ako vaš korisnički modul dodaje novo polje, ono će automatski biti dodato prilikom instalacije i uklonjeno prilikom deinstalacije modula.
Ako je modul već instaliran i želite da napišete hook_update_N za ažuriranje definicija polja, možete koristiti nešto poput:
/** * Dodaje highlight polje svim čvorovima. */ function MYMODULE_update_8001() { $entity_type = \Drupal::service('entity_type.manager')->getDefinition('node'); \Drupal::service('entity.definition_update_manager')->updateEntityType($entity_type); }
ili
/** * Dodaje 'revision_translation_affected' polje entitetima 'node'. */ function node_update_8001() { // Instalira definiciju koja je postojala u // \Drupal\node\Entity\Node::baseFieldDefinitions() // u vreme pisanja ove funkcije ažuriranja. Ako kasnije dođe do promene, // modul treba da implementira update funkciju koja poziva // \Drupal::entityDefinitionUpdateManager()->updateFieldStorageDefinition() // sa novom definicijom. $storage_definition = BaseFieldDefinition::create('boolean') ->setLabel(t('Revision translation affected')) ->setDescription(t('Indicates if the last edit of a translation belongs to current revision.')) ->setReadOnly(TRUE) ->setRevisionable(TRUE) ->setTranslatable(TRUE); \Drupal::entityDefinitionUpdateManager() ->installFieldStorageDefinition('revision_translation_affected', 'node', 'node', $storage_definition); }
Pogledajte https://www.drupal.org/node/2554097 za dodatne informacije i primere.
Rad sa definicijama polja
Napomena. Pošto su objekti složeni podaci, oni treba da prate ComplexDataInterface. Sa stanovišta Typed Data API-ja, svi tipizirani podaci unutar složenog objekta predstavljaju njegova svojstva. Ovo može biti ublaženo u budućnosti.
// Provera da li entitet ima određeno polje. $entity->hasField('field_tags'); // Vraća niz svih polja sa imenima i njihovim definicijama. Na primer, polje 'image'. $field_definitions = $entity->getFieldDefinitions(); // Vraća niz svojstava i njihovih definicija za data polja. Na primer, svojstva 'file_id' i 'alt' za polje 'image'. $property_definitions = $entity->image->getFieldDefinition()->getPropertyDefinitions(); // Vraća definiciju samo za svojstvo 'alt'. $alt_definition = $entity->image->getFieldDefinition()->getPropertyDefinition('alt'); // Definicije polja entiteta se takođe mogu dobiti preko menadžera entiteta, // sledeće vraća sva polja dostupna za sve bundle-ove. \Drupal::service('entity_field.manager')->getFieldStorageDefinitions($entity_type); // Sledeće vraća polja dostupna za dati bundle. \Drupal::service('entity_field.manager')->getFieldDefinitions($entity_type, $bundle);
Vidžeti i formaters za osnovna polja
Osnovna polja mogu da navode vidžete i formatere koje treba koristiti, kao i podesiva polja. Vidžet, formater i njihove opcije se podešavaju u klasi FieldDefinition na sledeći način:
use Drupal\Core\Field\BaseFieldDefinition; // ... $fields['title'] = BaseFieldDefinition::create('string') ->setLabel(t('Title')) ->setDescription(t('The title of this node, always treated as non-markup plain text.')) ->setRequired(TRUE) ->setTranslatable(TRUE) ->setSettings(array( 'default_value' => '', 'max_length' => 255, )) ->setDisplayOptions('view', array( 'label' => 'hidden', 'type' => 'string', 'weight' => -5, )) ->setDisplayOptions('form', array( 'type' => 'string', 'weight' => -5, )) ->setDisplayConfigurable('form', TRUE);
Ovde se koristi formatter „string“ i odgovarajući vidžet, kao i podešava težina polja naslova. setDisplayConfigurable() omogućava da polje bude vidljivo u korisničkom interfejsu za upravljanje prikazom forme i omogućava promenjivost reda i prikaza oznaka. Trenutno core ne dozvoljava promenu vidžeta ili njegovih podešavanja u UI.
Da biste podrazumevano sakrili polje, možete takođe podesiti ključ regiona u nizu koji prosleđujete setDisplayOptions() na „hidden“.
Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.