Content Entity Field-ի սահմանումն ու օգտագործումը
Content entities-ը պետք է բացահայտ սահմանեն իրենց բոլոր դաշտերը՝ տրամադրելով սահմանումներ entities դասի համար։ Դաշտերի սահմանումները հիմնված են Typed data API-ի վրա (տես՝ Ինչպես են էնտիթիները իրականացնում այն)։
Դաշտերի սահմանումներ
Էնտիթի տեսակները իրենց հիմնական դաշտերն ուρίζում են էնտիթի դասի ստատիկ մեթոդում։ Հիմնական դաշտերը չեն կարող հարմարեցվել և միշտ առկա են տվյալ էնտիթի տեսակում, օրինակ՝ նոդի անվանումը կամ ստեղծման և փոփոխության ամսաթիվը։ Էնտիթների մենեջերը լրացնում է դաշտերը հարմարեցված և չկոնֆիգուրացված դաշտերով, որոնք տրամադրում են այլ մոդուլներ՝ կանչելով hook_entity_field_info() և hook_entity_field_info_alter()։ Սա նաև այն կերպն է, որ Field UI-ի միջոցով կոնֆիգուրացված դաշտերը ավելանում են (դրանք այլևս գոյություն չունեն API-ի համաձայն)։
Դաշտերի սահմանումները պարզ օբյեկտներ են, որոնք իրականացնում են FieldDefinitionInterface ինտերֆեյսը, մինչդեռ հիմնական դաշտերը սովորաբար ստեղծվում են BaseFieldDefinition դասի միջոցով, իսկ հարմարեցված դաշտերը ուղղակիորեն իրականացնում են ինտերֆեյսը համապատասխան կոնֆիգուրացիոն օբյեկտներով (նաև կոչվում են Field և FieldInstance):
Դաշտերի սահմանումները նաև օգտագործվում են դաշտի էլեմենտի կամ էլեմենտի հատկության վերահսկող սահմանափակումներ սահմանելու համար։ Կարող են օգտագործվել դաշտի տիպի բոլոր պլագին իրականացումները։ (Այս ինտերֆեյսը և դասը այլևս գոյություն չունեն)։
Այժմ դաշտերը միշտ ներկայացվում են դաշտի էլեմենտների ցանկով, ինչը նշանակում է, որ FieldItem դասը, որը սահմանված է որպես տիպ, կփաթաթվի FieldItemList դասի մեջ, որը ներկայացնում է այդ դաշտի էլեմենտների ցանկը։
Բոլոր դաշտերն (ներառյալ հիմնականները) կարող են ունենալ նաև վիջեթներ և ձևաչափավորողներ իրենց ցուցադրման և խմբագրման համար։
Հիմնական դաշտեր
Ստորև ներկայացված է սեղմված օրինակ՝ նոդի էնտիթի տեսակի դաշտերի սահմանման։
use Drupal\Core\Field\BaseFieldDefinition; class Node implements NodeInterface { /** * {@inheritdoc} */ public static function baseFieldDefinitions($entity_type) { // Նոդի ID-ն ամբողջ թիվ է, օգտագործվում է IntegerItem դաշտի էլեմենտ դասը։ $fields['nid'] = BaseFieldDefinition::create('integer') ->setLabel(t('Node ID')) ->setDescription(t('Նոդի ID-ն։')) ->setReadOnly(TRUE); // UUID դաշտը օգտագործում է uuid_field տիպը, որը ապահովում է, որ նոր UUID-ն ավտոմատապես կստեղծվի էնտիթի ստեղծման ժամանակ։ $fields['uuid'] = BaseFieldDefinition::create('uuid') ->setLabel(t('UUID')) ->setDescription(t('Նոդի UUID-ն։')) ->setReadOnly(TRUE); // Լեզվի կոդը սահմանված է որպես language_field, որը ապահովում է նոր էնտիթիների համար լռելյայն գործող լեզվի կոդի ճիշտ սահմանումը։ $fields['langcode'] = BaseFieldDefinition::create('language') ->setLabel(t('Լեզվի կոդ')) ->setDescription(t('Նոդի լեզվի կոդը։')); // Անվանումը StringItem է, լռելյայն արժեքը դատարկ տող է և սահմանում է հատկության սահմանափակում, որ արժեքը չպետք է գերազանցի 255 նիշը։ $fields['title'] = BaseFieldDefinition::create('string') ->setLabel(t('Անվանում')) ->setDescription(t('Այս նոդի անվանումը, միշտ վերաբերվում է որպես ոչ-մարկացված պարզ տեքստ։')) ->setRequired(TRUE) ->setTranslatable(TRUE) ->setSettings(array( 'default_value' => '', 'max_length' => 255, )); // uid-ն է էնտիթի հղում օգտվողի էնտիթի տիպին, որը թույլ է տալիս $node->uid->target_id-ի միջոցով մուտք օգտվողի ID-ին և $node->uid->entity-ի միջոցով օգտվողի էնտիթի։ // NodeInterface-ն նաև սահմանում է getAuthor() և getAuthorId() մեթոդները։ (@todo՝ ստուգել owner-ի և revisionAuthor-ի տարբերությունը) $fields['uid'] = BaseFieldDefinition::create('entity_reference') ->setLabel(t('Օգտվողի ID')) ->setDescription(t('Նոդի հեղինակի օգտվողի ID-ն։')) ->setSettings(array( 'target_type' => 'user', 'default_value' => 0, )); // changed դաշտի տիպը ավտոմատ թարմացնում է ժամանակի կնիքը ամեն անգամ, երբ էնտիթին պահպանվում է։ $fields['changed'] = BaseFieldDefinition::create('changed') ->setLabel(t('Փոփոխված')) ->setDescription(t('Վերջին խմբագրման ժամանակը։')); return $fields; } }
Բազմահատոր դաշտեր
Դաշտի համար թույլատրելի էլեմենտների առավելագույն քանակը սահմանելու համար կանչեք setCardinality() մեթոդը։
Օրինակ՝ դաշտ սահմանելու համար, որը կարող է ունենալ 3 էլեմենտ՝
->setCardinality(3);
Դաշտ սահմանելու համար՝ որը կարող է ունենալ անսահմանափակ արժեքներ, կանչեք՝
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
Բազմաարժեք դաշտի օրինակ՝ օգտվողների էնտիթիների հղումով՝
$fields['my_field'] = BaseFieldDefinition::create('entity_reference') ->setLabel(t('Դաշտի պիտակը')) ->setDescription(t('Դաշտի նկարագրությունը։')) ->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);
Էնտիթին նաև կարող է տրամադրել դաշտեր, որոնք գոյություն ունեն միայն որոշակի փաթեթի համար կամ փոփոխվում են փաթեթի միջոցով։ Օրինակ՝ նոդի անվանումը կարող է ունենալ տարբեր պիտակներ յուրաքանչյուր փաթեթի համար։ Փաթեթի փոփոխությունները ապահովելու համար, հիմնական դաշտի սահմանումը պետք է կլոնավորվի նախքան փոփոխությունները, քանի որ հակառակ դեպքում կփոխվեր հիմնական դաշտի սահմանումը և ազդեր բոլոր փաթեթների վրա։
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; }
Դաշտերի տեսակը
Drupal-ի կորը տրամադրում է դաշտերի տեսակի ցուցակ, որոնք կարելի է օգտագործել հիմնական դաշտերի համար։ Բացի այդ, մոդուլները կարող են տրամադրել լրացուցիչ դաշտերի տեսակներ, որոնք նույնպես կարող են օգտագործվել։
- string: պարզ տող
- boolean: բուլյան արժեք, պահվում է որպես ամբողջ թիվ
- integer: ամբողջ թիվ՝ նվազագույն և առավելագույն արժեքների ստուգմամբ (առկա է նաև տասնորդական և լողացող կետով տիպեր)
- decimal: տասնորդական տիպ՝ ճշգրտությամբ և մասշտաբով
- float: լողացող կետով թիվ
- language: պարունակում է լեզվի կոդը և որպես հաշվարկվող հատկություն՝ լեզուն
- timestamp: Unix ժամանակի կնիք, պահվում է որպես ամբողջ թիվ
- created: ժամանակի կնիք, որն օգտագործում է ընթացիկ ժամանակը լռելյայն արժեքի համար
- changed: ժամանակի կնիք, որը ավտոմատ թարմացվում է վերջին պահպանման ժամանակ
- datetime: ամսաթիվը պահվում է ISO 8601 տողով
- uri: պարունակում է URI։ Link մոդուլն առաջարկում է նաև «link» դաշտի տիպ՝ որը կարող է ներառել հղման վերնագիր և մատնանշել ներքին կամ արտաքին URI/երթուղի
- uuid: UUID դաշտ, որը ավտոմատ ստեղծում է նոր UUID լռելյայն արժեքի համար
- email: էլեկտրոնային փոստ՝ համապատասխան ստուգումներով, վիջեթներով և ձևաչափավորողներով
- entity_reference: էնտիթի հղում՝ target_id-ով և հաշվողական էնտիթի հատկությամբ։ entity_reference մոդուլը տրամադրում է վիջեթներ և ձևաչափավորողներ ակտիվացման դեպքում
- map: կարող է պարունակել ցանկացած քանակությամբ произвольные հատկություններ՝ սերիալացված տողերով
Հարմարեցված դաշտեր
Լրացուցիչ դաշտերը կարելի է գրանցել hook_entity_base_field_info() և hook_entity_bundle_field_info() միջոցով։ Ստորև ներկայացված են օրինակներ, որտեղ ավելացվում են base և bundle դաշտեր։
use Drupal\Core\Field\BaseFieldDefinition; /** * Իրականացնում է 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('Դեպքի հասցե')) ->setComputed(TRUE); return $fields; } } /** * Իրականացնում է hook_entity_bundle_field_info()։ */ function field_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) { if ($entity_type->isFieldable()) { // Հարմարեցված դաշտերը, որոնք միշտ կապված են կոնկրետ փաթեթի հետ, ավելացվում են 'by bundle'։ return Field::fieldInfo()->getBundleInstances($entity_type->id(), $bundle); } }
Համապատասխան alter hook-եր գոյություն ունեն վերոհիշյալ յուրաքանչյուրի համար։
Տվյալների պահեստավորում
Եթե ձեր դաշտը չունի հատուկ պահանջներ, Entity Field API-ն հոգ է տանում տվյալների բազայի պահպանման և համապատասխանաբար թարմացնում է տվյալների բազայի սխեմաները։ Սա լռելյայն արժեքն է դաշտերի համար, որոնք չեն նշվել որպես հաշվարկվող դաշտեր (setComputed(TRUE)) կամ հատուկ չեն նշել սեփական դաշտային պահեստավորման տրամադրում (setCustomStorage(TRUE))։
Գիտենք, որ ուզում ենք ավելացնել նոր հիմնական դաշտ բոլոր Node էնտիթիների համար՝ պարզ boolean տիպով, որը նշի՝ արդյոք կոնտենտը առանձնացված է։
use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; /** * Իրականացնում է hook_entity_base_field_info()։ */ function MYMODULE_entity_base_field_info(EntityTypeInterface $entity_type) { $fields = array(); // Ավելացնում է 'Highlight' հիմնական դաշտը բոլոր նոդերի համար։ if ($entity_type->id() === 'node') { $fields['highlight'] = BaseFieldDefinition::create('boolean') ->setLabel(t('Հատուկ ընդգծում')) ->setDescription(t('Ցույց է տալիս՝ արդյոք նոդը առանձնացված է։')) ->setRevisionable(TRUE) ->setTranslatable(TRUE) ->setDisplayOptions('form', array( 'type' => 'boolean_checkbox', 'settings' => array( 'display_label' => TRUE, ), )) ->setDisplayConfigurable('form', TRUE); } return $fields; }
Ես բազմիցս փորձել եմ, բայց update.php այցելությունը դաշտի սյուն չի ավելացնում տվյալների բազայում, սակայն
\Drupal::entityTypeManager()->clearCachedDefinitions(); \Drupal::service('entity.definition_update_manager')->applyUpdates();
կարող է ստեղծել սյունը տվյալների բազայում։ Նշում. այս գործընթացում կգործարկվեն նաև բոլոր սպասող թարմացումները այլ դաշտերի սահմանումների համար։
Թարմացում․ վերոնշյալ կոդը չի աշխատի Drupal 8.7-ում։
Տեսեք օրինակ՝ այս փոփոխությունների գրառումից
Նոր դաշտային պահեստավորման սահմանման տեղադրում
function example_update_8701() { $field_storage_definition = BaseFieldDefinition::create('boolean') ->setLabel(t('Revision translation affected')) ->setDescription(t('Ցույց է տալիս՝ արդյոք թարգմանության վերջին խմբագրումը պատկանում է ընթացիկ վերանայմանը։')) ->setReadOnly(TRUE) ->setRevisionable(TRUE) ->setTranslatable(TRUE); \Drupal::entityDefinitionUpdateManager() ->installFieldStorageDefinition('revision_translation_affected', 'block_content', 'block_content', $field_storage_definition); }
Եթե ձեր հարմարեցված մոդուլը ավելացնում է նոր դաշտ, այն ավտոմատ կավելացվի մոդուլը ակտիվացնելիս և ջնջվելու է մոդուլը անջատելիս։
Եթե ձեր մոդուլն արդեն տեղադրված է և անհրաժեշտ է գրել hook_update_N թարմացման ֆունկցիա դաշտերի սահմանումները թարմացնելու համար, կարող եք անել հետևյալը՝
/** * Ավելացնում է highlight դաշտը բոլոր նոդերին։ */ function MYMODULE_update_8001() { $entity_type = \Drupal::service('entity_type.manager')->getDefinition('node'); \Drupal::service('entity.definition_update_manager')->updateEntityType($entity_type); }
կամ
/** * Ավելացնում է 'revision_translation_affected' դաշտը 'node' էնտիթիներին։ */ function node_update_8001() { // Տեղադրում է սահմանումը, որը այս դաշտը ունեցել է // \Drupal\node\Entity\Node::baseFieldDefinitions() մեթոդում // այն ժամանակ, երբ գրված է այս թարմացման ֆունկցիան։ Եթե/երբ կոդը փոխի այդ սահմանումը, // համապատասխան մոդուլը պետք է ունենա թարմացման ֆունկցիա, որը կանչի // \Drupal::entityDefinitionUpdateManager()->updateFieldStorageDefinition() // նոր սահմանմամբ։ $storage_definition = BaseFieldDefinition::create('boolean') ->setLabel(t('Revision translation affected')) ->setDescription(t('Ցույց է տալիս՝ արդյոք թարգմանության վերջին խմբագրումը պատկանում է ընթացիկ վերանայմանը։')) ->setReadOnly(TRUE) ->setRevisionable(TRUE) ->setTranslatable(TRUE); \Drupal::entityDefinitionUpdateManager() ->installFieldStorageDefinition('revision_translation_affected', 'node', 'node', $storage_definition); }
Տեսեք https://www.drupal.org/node/2554097 լրացուցիչ տեղեկությունների և օրինակների համար։
Դաշտերի սահմանումների հետ աշխատանքը
Նշում․ Քանի որ օբյեկտները բարդ տվյալներ են, դրանք պետք է հետևեն ComplexDataInterface-ին։ Typed data-ի տեսակետից բարդ օբյեկտում պարունակվող բոլոր տեսակավորված տվյալների էլեմենտները հանդիսանում են հատկություններ։ Այս սահմանափակումը/անվանակոչումը կարող է հանվել։
// Ստուգում է՝ արդյոք էնտիթին ունի կոնկրետ դաշտ։ $entity->hasField('field_tags'); // Վերադարձնում է դաշտերի զանգված՝ անվանով բոլոր դաշտերի և նրանց սահմանումների համար։ Օրինակ՝ 'image' դաշտի համար։ $field_definitions = $entity->getFieldDefinitions(); // Վերադարձնում է դաշտի էլեմենտների հատկությունների զանգվածը՝ անուններով, օրինակ՝ 'file_id' և 'alt' հատկությունները։ $property_definitions = $entity->image->getFieldDefinition()->getPropertyDefinitions(); // Վերադարձնում է միայն 'alt' հատկության սահմանումը։ $alt_definition = $entity->image->getFieldDefinition()->getPropertyDefinition('alt'); // Էնտիթի դաշտերի սահմանումները կարելի է նաև խնդրել էնտիթի մենեջերից՝ հետևյալը վերադարձնում է բոլոր դաշտերը, որոնք հասանելի են բոլոր փաթեթների համար։ \Drupal::service('entity_field.manager')->getFieldStorageDefinitions($entity_type); // Ստորև ներկայացվում են տվյալ փաթեթի համար հասանելի դաշտերը։ \Drupal::service('entity_field.manager')->getFieldDefinitions($entity_type, $bundle);
Հիմնական դաշտերի վիջեթներն ու ձևաչափավորողները
Հիմնական դաշտերը կարող են սահմանել վիջեթներ և ձևաչափավորողներ, որոնք պետք է օգտագործեն, ինչպես նաև հարմարեցված դաշտերը։ Վիջեթը և ձևաչափավորողը և անհրաժեշտ պարամետրերը սահմանվում են FieldDefinition դասում հետևյալ կերպ՝
use Drupal\Core\Field\BaseFieldDefinition; // ... $fields['title'] = BaseFieldDefinition::create('string') ->setLabel(t('Անվանում')) ->setDescription(t('Այս նոդի անվանումը, միշտ վերաբերվում է որպես ոչ-մարկացված պարզ տեքստ։')) ->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);
Այս դեպքում օգտագործվում են 'string' ձևաչափավորողն ու վիջեթը, և սահմանվում է նոդի անվան կշիռը։ setDisplayConfigurable() կարելի է օգտագործել դաշտը դարձնելու տեսանելի ձևի կառավարման UI-ում, որպեսզի հնարավոր լինի փոփոխել դաշտերի հերթականությունը և պիտակների ցուցադրումը։ Ներկայում Drupal-ի կորի մեջ հնարավոր չէ փոփոխել վիջեթը կամ դրա պարամետրերը UI-ում։
Դաշտը լռելյայն դարձնելու համար կարող եք նաև սահմանել տարածաշրջանային բանալի setDisplayOptions() զանգվածում՝ նշանակելով այն որպես թաքնված։
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.