我正在创建一个包含引号,名称,公司和可选头像的新字段类型。
我的代码在
下面modules/mymodule/src/FieldType/Testimonial.php
<?php
namespace Drupal\dods\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\TypedData\DataDefinition;
use Drupal\Core\Field\FieldStorageDefinitionInterface as StorageDefinition;
/**
* Plugin implementation of the 'Testimonial' field type.
*
* @FieldType(
* id = "Testimonial",
* label = @Translation("Testimonial"),
* description = @Translation("Stores Testimonial Information."),
* category = @Translation("Custom"),
* default_widget = "TestimonialDefaultWidget",
* default_formatter = "TestimonialDefaultFormatter"
* )
*
* Class Testimonial
* @package Drupal\dods\Plugin\Field\FieldType
*/
class Testimonial extends FieldItemBase
{
/**
* Field type properties definition.
*
* Inside this method we defines all the fields (properties) that our
* custom field type will have.
*
* @param StorageDefinition $storage
* @return array
*/
public static function propertyDefinitions(StorageDefinition $storage)
{
$properties['testimonial_quote'] = DataDefinition::create('string')->setLabel(t('Quote'));
$properties['testimonial_name'] = DataDefinition::create('string')->setLabel(t('Name'));
$properties['testimonial_company'] = DataDefinition::create('string')->setLabel(t('Company'));
$properties['testimonial_headshot'] = DataDefinition::create('integer')->setLabel(t('Headshot'));
return $properties;
}
/**
* Field type schema definition.
*
* Inside this method we defines the database schema used to store data for
* our field type.
* @param StorageDefinition $storage
* @return array
*/
public static function schema(StorageDefinition $storage)
{
$schema['columns']['testimonial_quote'] = ['type' => 'text'];
$schema['columns']['testimonial_name'] = ['type' => 'char', 'length' => 100];
$schema['columns']['testimonial_company'] = ['type' => 'char', 'length' => 100];
$schema['columns']['testimonial_headshot'] = ['type' => 'int'];
return $schema;
}
/**
* Define when the field type is empty.
*
* This method is important and used internally by Drupal. Take a moment
* to define when the field type must be considered empty.
*
* @return bool
*/
public function isEmpty()
{
return empty($this->get('testimonial_quote')->getValue()) && empty($this->get('testimonial_name')->getValue()) && empty($this->get('testimonial_company')->getValue());
}
}
我的小部件看起来像这样
modules/mymodule/src/Plugin/Field/FieldWidget/TestimonialDefaultWidget.php
<?php
namespace Drupal\dods\Plugin\Field\FieldWidget;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Plugin implementation of the 'TestimonialDefaultWidget' widget.
*
* @FieldWidget(
* id = "TestimonialDefaultWidget",
* label = @Translation("Testimonial Information"),
* field_types = {
* "Testimonial"
* }
* )
*
* Class TestimonialDefaultWidget
* @package Drupal\dods\Plugin\Field\FieldWidget
*/
class TestimonialDefaultWidget extends WidgetBase
{
/**
* Define the form for the field type.
*
* Inside this method we can define the form used to edit the field type.
*
* @param FieldItemListInterface $items
* @param int $delta
* @param array $element
* @param array $form
* @param FormStateInterface $formState
* @return array
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $formState)
{
$element['testimonial_quote'] = [
'#type' => 'textarea',
'#title' => t('Quote'),
'#default_value' => isset($items[$delta]->testimonial_quote) ? $items[$delta]->testimonial_quote : null,
'#empty_value' => '',
'#placeholder' => t('Quote'),
];
$element['testimonial_name'] = [
'#type' => 'textfield',
'#title' => t('Name'),
'#default_value' => isset($items[$delta]->testimonial_name) ? $items[$delta]->testimonial_name : null,
'#empty_value' => '',
'#placeholder' => t('Name'),
];
$element['testimonial_company'] = [
'#type' => 'textfield',
'#title' => t('Company'),
'#default_value' => isset($items[$delta]->testimonial_company) ? $items[$delta]->testimonial_company : null,
'#empty_value' => '',
'#placeholder' => t('Company'),
];
$element['testimonial_headshot'] = array(
'#type' => 'managed_file',
'#upload_validators' => array(
'file_validate_extensions' => array('gif png jpg jpeg'),
'file_validate_size' => array(25600000),
),
'#required' => false
);
return $element;
}
}
一切看起来很好,但是当我尝试保存任何东西时,我都会收到此错误
此值应为正确的基本类型。
任何想法我都会感激我碰到了一堵砖墙:(
更新
感觉有点hacky但是为了得到这个工作我必须做以下
添加formElement()
$element['testimonial_headshot_revision'] = [
'#type' => 'hidden',
'#default_value' => isset($items[$delta]->testimonial_headshot) ? $items[$delta]->testimonial_headshot : null
];
在同一个文件中添加一个新功能,如此
/**
* {@inheritdoc}
*/
public function massageFormValues(array $values, array $form, FormStateInterface $form_state)
{
foreach ($values as &$value) {
if (count($value['testimonial_headshot'])) {
foreach ($value['testimonial_headshot'] as $fid) {
$value['testimonial_headshot'] = $fid;
}
} else {
$value['testimonial_headshot'] = $value['testimonial_headshot_revision'] !== '' ? $value['testimonial_headshot_revision'] : '0';
}
}
return $values;
}
答案 0 :(得分:0)
这是因为您将testimonial_headshot
定义为int
,但提供了文件上传小部件。作为一般提示:每当你编程&#34;新&#34;这些东西,看看你是否能找到与你尝试做的类似的东西,然后只是扩展/修改它。
实施例:
对我来说,你的新领域基本上是一个带有一些额外文本字段的图像字段。所以你可以做的是查看ImageItem字段类型并使用testimonial_quote
等扩展它。
所以你的新字段类型可能如下所示:
class TestimonialItem extends ImageItem
然后:
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
// get the image item properties
$properties = parent::propertyDefinitions($field_definition);
// if you don't need some properties of the parent do this:
unset($properties['some_property_of_parent']);
// add your thing
$properties['testimonial_quote'] = DataDefinition::create('string')
->setLabel(t('Quote'))
->setDescription(t("This is the quote of the testimonial"));
// etc.
return $properties;
}
这是主要的想法,对schema()
方法和小部件类也这样做。抓住父母并扩展它。
希望这有帮助。