Դաշտի տեսակներ, դաշտի վիջեթներ և դաշտի ձևաչափավորիչներ
Վերանայում
Drupal 8-ն ունի մեծ հավաքածու հիմնական դասերի, որոնք թույլ են տալիս աշխատել ձեր սեփական կոնտենտի հետ։ Երբ խոսքը գնում է կոնտենտի էնտիթիների մասին, դուք ցանկանում եք օգտագործել դաշտեր։ Կարևոր է հասկանալ դաշտերը, քանի որ հենց այնտեղ են ձեր էնտիթիները պահում իրենց տվյալները։
Դաշտի տեսակներ (FieldTypes)
Հիմնական դաշտի տեսակներն են՝
- boolean
- changed
- comment
- created
- datetime
- daterange
- decimal
- entity_reference
- file
- float
- image
- integer
- language
- link
- list_float
- list_integer
- list_string
- map
- password
- path
- string
- string_long
- telephone
- text
- text_long
- text_with_summary
- timestamp
- uri
- uuid
Հարմարեցված դաշտերի տեսակներ
Երբևէ, երբ ցանկանում եք ներկայացնել տվյալներ այնպես, ինչպես Drupal չի առաջարկում, հնարավոր է ցանկանաք ստեղծել նոր դաշտի տեսակ ձեր տվյալների համար։
Ուրեմն, պատկերացրեք, որ ունեք կոնտենտի էնտիթի, որը պարունակում է գաղտնի տվյալներ։ Այդ կոնտենտի հեղինակը կարող է որոշակի օգտվողների թույլատրել մուտք ունենալ այդ էնտիթի՝ յուրաքանյուր օգտվողի համար տարբեր գաղտնաբառով։ Եթե պատկերացնենք դա տվյալների բազայի աղյուսակներում, ապա ցանկանում եք ունենալ ինչ-որ նման բան՝
| entity_id | uid | password | ----------------------------------- | 1 | 1 | 'helloworld' | | 1 | 2 | 'goodbye' |
Ինչպես տեսնում եք, մեր էնտիթին՝ ID 1, ունի երկու տարբեր գաղտնաբառ երկու տարբեր օգտվողների համար։ Հետեւաբար, ինչպես կարող ենք իրականացնել սա Drupal-ում՝ առանց ձեռքով աղյուսակ ստեղծելու։ Մենք ստեղծում ենք նոր դաշտի տեսակ։
Քանի որ Drupal-ում դաշտի տրամաբանությունը իրականացնում է որպես Պլագին, մենք միշտ ունենք հիմքային դաս, որը ժառանգում ենք, որպեսզի այն աշխատի Drupal-ում։ Նոր դաշտի տեսակի համար դուք պետք է ստեղծեք հետևյալ թղթապանակների կառուցվածքը ձեր մոդուլում՝
modules/custom/MODULENAME/src/Plugin/Field/FieldType
Սա բավականին երկար ուղի է և մի քիչ ձանձրալի, բայց Drupal-ը հեշտացնում է աշխատանքը բոլոր տարբեր ֆունկցիաների հետ, որոնք կարող են համատեղ գոյություն ունենալ ձեր մոդուլներում։
Մեր օրինակին համար մենք ստեղծում ենք EntityUserAccessField.php ֆայլը
namespace Drupal\MODULENAME\Plugin\Field\FieldType; use Drupal\Core\Field\FieldItemBase; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\TypedData\DataDefinition; /** * @FieldType( * id = "entity_user_access", * label = @Translation("Entity User Access"), * description = @Translation("Այս դաշտը պահպանում է հղում օգտվողի և գաղտնաբառի համար էնտիթի վրա։"), * ) */ class EntityUserAccessField extends FieldItemBase { /** * {@inheritdoc} */ public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) { // Todo: Կիրառել սա։ } /** * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { // Todo: Կիրառել սա։ } }
Ինչպես տեսնում եք, դաշտի տեսակն շատ նման է կոնտենտի էնտիթի։ Իրականում, նրանց միջև տարբերություն չկա, բայց դա արդեն առանձին թեմա է։
Առաջին հերթին, մենք ունենք անշանագրում մեր դաշտի տեսակի համար՝
- @FieldType՝ կանչում է FieldType անշանագրման դասը Drupal գրադարանում
- id՝ դաշտի տեսակի մեքենայական անունը, որպեսզի մենք կարողանանք այն կրկնօրինակել։ Համոզվեք, որ չեք վերագրանցում արդեն գոյություն ունեցող PHP կամ նման անունները։
- label՝ կարող է լինել օգտվողի համար ընթեռնելի մեքենայական անվան թարգմանություն։
- description՝ եթե պիտակները բավարար չեն, կարող եք ավելացնել դաշտի տեսակի նկարագրություն։
Երկրորդ, մեր դասը ժառանգվում է FieldItemBase-ից, որը պարտադրում է մեզ իրականացնել երկու մեթոդ, որպեսզի կարողանանք ճիշտ օգտագործել դաշտի այս տեսակը՝
- propertyDefinitions(): Այս մեթոդը նման է baseFieldDefinition մեթոդին կոնտենտի էնտիթի համար (սակայն նույնը չէ)։ Մենք կարող ենք սահմանել տվյալները, որոնք երևում են էնտիթի ձևերում, որտեղ օգտագործվում է այս դաշտի տեսակն։
- schema(): Այս մեթոդը արդեն հնացել է էնտիթի դեպքում, բայց դաշտերի համար դեռ կա։ Այն պետք է իրականացնի դաշտի տվյալների ներկայացումը տվյալների բազայում։ Կարող է տարբեր լինել propertyDefinitions-ում նշված հատկություններից։
Քանի որ դժվար է հասկանալ, թե ինչ պետք է գրենք այս մեթոդներում, եկեք ավելացնենք նրանց մեջ որոշ կոդ հարմարության համար։
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) { $properties['uid'] = DataDefinition::create('integer') ->setLabel(t('Օգտվողի ID-ի հղում')) ->setDescription(t('Հղված օգտվողի ID-ն։')) ->setSetting('unsigned', TRUE); $properties['password'] = DataDefinition::create('string') ->setLabel(t('Գաղտնաբառ')) ->setDescription(t('Գաղտնաբառը պահպանված է պարզ տեքստով։ Դա անվտանգ չէ!')); $properties['created'] = DataDefinition::create('timestamp') ->setLabel(t('Ստեղծման ժամանակը')) ->setDescription(t('Ներմանության ստեղծման ժամանակը')); // Todo: Ավելացնել ավելի շատ հատկություններ։ return $properties; }
Նմանապես հնարավոր է օգտագործել DataReferenceDefinition՝ օգտվողի ID պահելու համար, ինչը կարող է քննարկվել ապագայում։
public static function schema(FieldStorageDefinitionInterface $field_definition) { $columns = array( 'uid' => array( 'description' => 'Հղված օգտվողի ID-ն։', 'type' => 'int', 'unsigned' => TRUE, ), 'password' => array( 'description' => 'Պարզ տեքստով գաղտնաբառ։', 'type' => 'varchar', 'length' => 255, ), 'created' => array( 'description' => 'Ժամանակահատվածը, երբ այս նիշումն ստեղծվել է։', 'type' => 'int', ), // Todo: Ավելացնել ավելի շատ սյուներ։ ); $schema = array( 'columns' => $columns, 'indexes' => array(), 'foreign keys' => array(), ); return $schema; }
schema() մեթոդը անհրաժեշտ է, որպեսզի Drupal-ը իմանա, թե ինչպես պահել մեր տվյալները։ Schema-ի սյուները պետք է լինեն propertyDefinitions-ում սահմանված հատկությունների ենթավիճակ։
Այժմ մենք ունենք նոր դաշտի տեսակ։ Այն չունի որևէ տրամաբանություն տվյալների մուտքագրման մշակման համար, բայց կարող է օգտագործվել ցանկացած կոնտենտի էնտիթի դաշտի նման։ Եթե ցանկանում եք, կարող եք օգտագործել այն որպես baseField ձեր էնտիթի համար՝
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { // Որոշ դաշտեր վերևում։ $fields['entity_user_access'] = BaseFieldDefinition::create('entity_user_access') ->setLabel(t('Entity User Access')) ->setDescription(t('Նշեք գաղտնաբառերը ցանկացած օգտվողի համար, ով ցանկանում է դիտել այս էնտիթին։')) ->setCardinality(-1); // Գործնականում թույլ է տալիս ունենալ ավելի քան մեկ արժեք // Ավելի շատ դաշտեր ներքևում։ return $fields; }
- BaseFieldDefinition::create(): Դուք պետք է օգտագործեք դաշտի տեսակի մեքենայական անունը create() մեթոդում։
- setCardinality(-1): Նշում է, թե քանի արժեք կարող է ունենալ մեկ դաշտի օբյեկտը։ Օրինակ, եթե դրեք 2, ապա միայն երկու օգտվող կարող է մուտք ունենալ, 3՝ երեք օգտվող և այլն։ -1 նշանակում է անսահմանափակ թվով օգտվողներ։
Դաշտի Վիջեթներ (FieldWidget)
Եթե դուք ունեք հարմարեցված տվյալներ, ապա ձեզ կարող է անհրաժեշտ լինել այդ տվյալների հարմարեցված ներկայացում։ Վիջեթները օգտագործվում են ցույց տալու, թե ինչպես կարող է օգտվողը մուտքագրել այդ տվյալները ձևերում։ Օրինակ՝
- եթե ձևում պետք է մուտքագրել ամբողջ թիվ, բայց օգտվողը կարող է պարզապես ընտրել միակ զննարկիչը (checkbox)
- եթե ցանկանում եք ձեր տվյալների ավտոմատ լրացում
- եթե գաղտնաբառը մուտքագրվում է հատուկ ինտերֆեյսով
և այլն։
Դաշտի վիջեթները Drupal-ում կարող եք գտնել
modules/custom/MODULENAME/src/Plugin/Field/FieldWidget
այսինքն բավական երկար ճանապարհ է։ Այստեղ պետք է հասկանաք, թե ինչու Drupal-ը այսպես է կազմակերպում .php ֆայլերը․ հեշտ է կորցնել, թե որ ֆայլը որտեղ է պատկանում։
Մենք ստեղծում ենք դաշտի վիջեթը EntityUserAccessWidget.php
namespace Drupal\MODULENAME\Plugin\Field\FieldWidget; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Field\WidgetBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; /** * Plugin implementation of the 'entity_user_access_w' widget. * * @FieldWidget( * id = "entity_user_access_w", * label = @Translation("Entity User Access - Widget"), * description = @Translation("Entity User Access - Widget"), * field_types = { * "entity_user_access", * }, * multiple_values = TRUE, * ) */ class EntityUserAccessWidget extends WidgetBase { /** * {@inheritdoc} */ public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { // Todo: Կիրառել սա։ } }
Դուք նկատե՞լ եք։ Drupal 8-ում այս կոդային ոճը կրկնվում է միշտ, երբ ցանկանում եք իրականացնել ֆունկցիոնալություն։ Կան անշանագրումներ և հիմքային դասեր, որոնք պետք է ժառանգել։ Այո, Drupal-ը կարող է այսպես աշխատել։
- @FieldWidget՝ սահմանում է անշանագրման դասը
- id՝ վիջեթի մեքենայական անունը
- field_types՝ դաշտի տեսակի մեքենայական անունների զանգվածը, որոնց համար կարելի է օգտագործել այս վիջեթը
- multiple_values՝ լռելյայն FALSE է։ Եթե ճիշտ է, թույլ է տալիս մեկից ավելի արժեք ուղարկել էնտիթի ձևում
Եթե հիմա ցանկանում եք օգտագործել այս վիջեթը ձեր դաշտի տեսակի հետ, պետք է խմբագրեք դաշտի տեսակի անշանագրումը այսպես՝
// ... /** * @FieldType( * id = "entity_user_access", * label = @Translation("Entity User Access"), * description = @Translation("Այս դաշտը պահպանում է հղում օգտվողի և գաղտնաբառի համար էնտիթի վրա։"), * default_widget = "entity_user_access_w", * ) */ // ...
Այժմ ամեն ինչ պատրաստ է։ Բայց մի սպասեք փոփոխություններ, քանի որ պետք է իրականացնել formElement() մեթոդը մեր վիջեթում։
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { $element['userlist'] = array( '#type' => 'select', '#title' => t('Օգտվող'), '#description' => t('Ընտրեք խմբի անդամներին ցուցակից։'), '#options' => array( 0 => t('Անանուն'), 1 => t('Ադմինիստրատոր'), 2 => t('foobar'), // Սա պետք է ավելի լավ իրականացվի։ ), ); $element['passwordlist'] = array( '#type' => 'password', '#title' => t('Գաղտնաբառ'), '#description' => t('Ընտրեք գաղտնաբառը օգտվողի համար'), ); // Գտնել լռելյայն արժեքը բոլոր դաշտերի համար վերևում $childs = Element::children($element); foreach ($childs as $child) { $element[$child]['#default_value'] = isset($items[$delta]->{$child}) ? $items[$delta]->{$child} : NULL; } return $element; }
Եթե հիմա բացեք ձևը այս վիջեթով, կտեսնեք առնվազն երկու մուտքի դաշտ։ Մեկը օգտվողի ընտրությունն է, մյուսը՝ գաղտնաբառի դաշտը։ Եթե ցանկանում եք իրականացնել տվյալների պահպանման եղանակ, պետք է ավելացնել ստուգման մեթոդներ այս վիջեթում կամ էնտիթի ձևում։ Տեսեք Drupal 8 Form API-ն ավելին իմանալու համար։
Դուք արդեն կատարել եք հարմարեցված դաշտի մեծ մասը։ Եթե չեք հասկանում, թե ինչ է տեղի ունենում, փորձեք կոդը կամ ուսումնասիրեք հիմնական մոդուլները ավելի լավ ընկալման համար։
Դաշտի ձևաչափավորիչներ (FieldFormatters)
Վերջին մասը, որը պակասում է, տվյալների ներկայացումն է էնտիթի դիտման ռեժիմում (իսկ վիջեթը՝ ձևի ռեժիմում)։ Դա սովորաբար տեղի է ունենում, երբ կանչում եք էնտիթին՝ yourdrupalpage.com/myentity/1/view հասցեով։
Որպեսզի շատ չխոսենք, անցնենք անմիջապես կոդին։ modules/custom/MODULENAME/src/Plugin/Field/FieldFormatter թղթապանակում ստեղծեք EntityUserAccessFormatter.php ֆայլը։
namespace Drupal\MODULENAME\Plugin\Field\FieldFormatter; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Field\FormatterBase; /** * Plugin implementation of the 'entity_user_access_f' formatter. * * @FieldFormatter( * id = "entity_user_access_f", * label = @Translation("Entity User Access - Formatter"), * description = @Translation("Entity User Access - Formatter"), * field_types = { * "entity_user_access", * } * ) */ class EntityUserAccessFormatter extends FormatterBase { /** * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items, $langcode) { $elements = array(); foreach ($items as $delta => $item) { $elements[$delta] = array( 'uid' => array( '#markup' => \Drupal\user\Entity\User::load($item->uid)->getUsername(), ), // Ավելացնել ավելի բովանդակություն ); } return $elements; } }
Այս օրինակն ունի շատ նման անշանագրություն, ինչպիսին վիջեթն էր, ուստի շատ բան չպետք է խոսենք։ viewElements() մեթոդը պարզապես ցույց է տալիս օգտագործողի անունը, որը պահպանված է դաշտի տեսակին պատկանող օգտվողի ID-ի միջոցով։ Դասի մուտքի հասանելիությունը պետք է իրականացվի էնտիթի մակարդակով։ Այսպիսով, այս իրականացումը ցույց կտա բոլոր օգտվողների անունները, ովքեր ունեն գաղտնաբառ տվյալ էնտիթի վրա։
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.