class FileLinkItem in File Link 8
Same name and namespace in other branches
- 2.0.x src/Plugin/Field/FieldType/FileLinkItem.php \Drupal\file_link\Plugin\Field\FieldType\FileLinkItem
Implements a 'file_link' plugin field type.
This field type is an extension of 'link' filed-type that points only to files, not to directories and, additionally, stores some meta-data related to targeted file, like size and mime-type.
Plugin annotation
@FieldType(
id = "file_link",
label = @Translation("File Link"),
description = @Translation("Stores a URL string pointing to a file, optional varchar link text, and file metadata, like size and mime-type."),
default_widget = "file_link_default",
default_formatter = "link",
constraints = {
"LinkAccess" = {},
"LinkToFile" = {},
"LinkExternalProtocols" = {},
"LinkNotExistingInternal" = {}
}
)
Hierarchy
- class \Drupal\Core\TypedData\TypedData implements PluginInspectionInterface, TypedDataInterface uses DependencySerializationTrait, StringTranslationTrait, TypedDataTrait
- class \Drupal\Core\TypedData\Plugin\DataType\Map implements \Drupal\Core\TypedData\Plugin\DataType\IteratorAggregate, ComplexDataInterface
- class \Drupal\Core\Field\FieldItemBase implements FieldItemInterface
- class \Drupal\link\Plugin\Field\FieldType\LinkItem implements LinkItemInterface
- class \Drupal\file_link\Plugin\Field\FieldType\FileLinkItem implements FileLinkInterface
- class \Drupal\link\Plugin\Field\FieldType\LinkItem implements LinkItemInterface
- class \Drupal\Core\Field\FieldItemBase implements FieldItemInterface
- class \Drupal\Core\TypedData\Plugin\DataType\Map implements \Drupal\Core\TypedData\Plugin\DataType\IteratorAggregate, ComplexDataInterface
Expanded class hierarchy of FileLinkItem
1 file declares its use of FileLinkItem
- LinkToFileConstraint.php in src/
Plugin/ Validation/ Constraint/ LinkToFileConstraint.php
File
- src/
Plugin/ Field/ FieldType/ FileLinkItem.php, line 38
Namespace
Drupal\file_link\Plugin\Field\FieldTypeView source
class FileLinkItem extends LinkItem implements FileLinkInterface {
/**
* The HTTP response of the last client request, if any.
*
* @var \Psr\Http\Message\ResponseInterface
*/
protected $response = NULL;
/**
* The exception throw by the the last HTTP client request, if any.
*
* @var \GuzzleHttp\Exception\RequestException
*/
protected $exception = NULL;
/**
* The entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The HTTP client service.
*
* @var \GuzzleHttp\Client
*/
protected $httpClient;
/**
* {@inheritdoc}
*/
public static function defaultFieldSettings() {
return [
'file_extensions' => 'txt',
'no_extension' => FALSE,
] + parent::defaultFieldSettings();
}
/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
return parent::propertyDefinitions($field_definition) + [
'size' => DataDefinition::create('integer')
->setLabel(t('Size')),
'format' => DataDefinition::create('string')
->setLabel(t('Format')),
];
}
/**
* {@inheritdoc}
*/
public static function schema(FieldStorageDefinitionInterface $field_definition) {
$schema = parent::schema($field_definition);
$schema['columns']['size'] = [
'description' => 'The size of the file.',
'type' => 'int',
'size' => 'big',
'unsigned' => TRUE,
];
$schema['columns']['format'] = [
'description' => 'The format of the file.',
'type' => 'varchar',
'length' => 255,
];
$schema['indexes']['size'] = [
'size',
];
$schema['indexes']['format'] = [
'format',
];
return $schema;
}
/**
* {@inheritdoc}
*/
public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
$element = parent::fieldSettingsForm($form, $form_state);
// Make the extension list a little more human-friendly by comma-separation.
$extensions = str_replace(' ', ', ', $this
->getSetting('file_extensions'));
$element['file_extensions'] = [
'#type' => 'textfield',
'#title' => $this
->t('Allowed file extensions'),
'#default_value' => $extensions,
'#description' => $this
->t('Separate extensions with a space or comma and do not include the leading dot. Leave empty to allow any extension.'),
// Use the 'file' field type validator.
'#element_validate' => [
[
FileItem::class,
'validateExtensions',
],
],
'#maxlength' => 256,
];
$element['no_extension'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Allow URLs without file extension'),
'#description' => $this
->t('The link can refer a document such as a wiki page or a dynamic generated page that has no extension. Check this if you want to allow such URLs.'),
'#default_value' => $this
->getSetting('no_extension'),
];
return $element;
}
/**
* {@inheritdoc}
*/
public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
$values = parent::generateSampleValue($field_definition);
$values['size'] = 1234567;
$values['format'] = 'image/png';
return $values;
}
/**
* {@inheritdoc}
*/
public function preSave() {
parent::preSave();
// Skip performing HTTP requests, useful when running bulk imports.
if (Settings::get('file_link.disable_http_requests', FALSE)) {
return;
}
$entity = $this
->getEntity();
$storage = $this
->getEntityTypeManager()
->getStorage($entity
->getEntityTypeId());
/** @var \Drupal\Core\Entity\ContentEntityInterface $original */
$original = $entity
->isNew() ? NULL : $storage
->loadUnchanged($entity
->id());
$field_name = $this
->getFieldDefinition()
->getName();
$original_uri = $original ? $original->{$field_name}->uri : NULL;
$size = $original ? $original->{$field_name}->size : NULL;
$format = $original ? $original->{$field_name}->format : NULL;
// We parse the metadata in any of the next cases:
// - The host entity is new.
// - The 'file_link' URI has changed.
// - Stored metadata is empty, possible due to an previous failure. We try
// again to parse, hoping the connection was fixed in the meantime.
$needs_parsing = $entity
->isNew() || $this->uri !== $original_uri || empty($size) || empty($format);
if ($needs_parsing) {
// Don't throw exceptions on HTTP level errors (e.g. 404, 403, etc).
$options = [
'exceptions' => FALSE,
'allow_redirects' => [
'strict' => TRUE,
],
];
$url = Url::fromUri($this->uri, [
'absolute' => TRUE,
])
->toString();
// Clear any previous stored results (response and/or exception).
$this
->clearResponse();
$this
->clearException();
try {
// Perform only a HEAD method to save bandwidth.
$this
->setResponse($this
->getHttpClient()
->head($url, $options));
} catch (RequestException $request_exception) {
$this
->setException($request_exception);
}
$format = NULL;
$size = 0;
if (!$this
->getException() && ($response = $this
->getResponse()) && $this
->isSupportedResponse($response)) {
if ($response
->hasHeader('Content-Type')) {
// The format may have the pattern 'text/html; charset=UTF-8'. In this
// case, keep only the first relevant part.
$format = explode(';', $response
->getHeaderLine('Content-Type'))[0];
}
else {
$format = NULL;
}
if ($response
->hasHeader('Content-Length')) {
$size = (int) $response
->getHeaderLine('Content-Length');
}
else {
// The server didn't sent the Content-Length header. In this case,
// perform a full GET and measure the size of the returned body.
$response = $this
->getHttpClient()
->get($url, $options);
$size = (int) $response
->getBody()
->getSize();
$this
->setResponse($response);
}
$this
->writePropertyValue('size', $size);
$this
->writePropertyValue('format', $format);
}
}
}
/**
* {@inheritdoc}
*/
public function getSize() {
return $this
->get('size')
->getValue();
}
/**
* {@inheritdoc}
*/
public function getFormat() {
return $this
->get('format')
->getValue();
}
/**
* {@inheritdoc}
*/
public function setResponse(ResponseInterface $response) {
$this->response = $response;
return $this;
}
/**
* {@inheritdoc}
*/
public function getResponse() {
return $this->response;
}
/**
* {@inheritdoc}
*/
public function clearResponse() {
$this->response = NULL;
return $this;
}
/**
* {@inheritdoc}
*/
public function setException(RequestException $exception) {
$this->exception = $exception;
return $this;
}
/**
* {@inheritdoc}
*/
public function getException() {
return $this->exception;
}
/**
* {@inheritdoc}
*/
public function clearException() {
$this->exception = NULL;
return $this;
}
/**
* Returns the entity type manager service.
*
* @return \Drupal\Core\Entity\EntityTypeManagerInterface
* The entity type manager service.
*/
protected function getEntityTypeManager() {
if (!isset($this->entityTypeManager)) {
$this->entityTypeManager = \Drupal::entityTypeManager();
}
return $this->entityTypeManager;
}
/**
* Returns the HTTP client service.
*
* @return \GuzzleHttp\Client
* The Guzzle client.
*/
protected function getHttpClient() {
if (!isset($this->httpClient)) {
$this->httpClient = \Drupal::httpClient();
}
return $this->httpClient;
}
/**
* Check whereas given response is supported by field type.
*
* @param \Psr\Http\Message\ResponseInterface $response
* Response object.
*
* @return bool
* TRUE if supported, FALSE otherwise.
*/
protected function isSupportedResponse(ResponseInterface $response) {
return in_array($response
->getStatusCode(), [
'200',
'301',
'302',
]);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
FieldItemBase:: |
public static | function |
Calculates dependencies for field items. Overrides FieldItemInterface:: |
2 |
FieldItemBase:: |
public static | function |
Calculates dependencies for field items on the storage level. Overrides FieldItemInterface:: |
1 |
FieldItemBase:: |
public static | function |
Defines the storage-level settings for this plugin. Overrides FieldItemInterface:: |
10 |
FieldItemBase:: |
public | function |
Defines custom delete behavior for field values. Overrides FieldItemInterface:: |
2 |
FieldItemBase:: |
public | function |
Defines custom revision delete behavior for field values. Overrides FieldItemInterface:: |
|
FieldItemBase:: |
public static | function |
Returns a settings array in the field type's canonical representation. Overrides FieldItemInterface:: |
1 |
FieldItemBase:: |
public static | function |
Returns a settings array that can be stored as a configuration value. Overrides FieldItemInterface:: |
1 |
FieldItemBase:: |
public | function |
Gets the entity that field belongs to. Overrides FieldItemInterface:: |
|
FieldItemBase:: |
public | function |
Gets the field definition. Overrides FieldItemInterface:: |
|
FieldItemBase:: |
public | function |
Gets the langcode of the field values held in the object. Overrides FieldItemInterface:: |
|
FieldItemBase:: |
protected | function | Returns the value of a field setting. | |
FieldItemBase:: |
protected | function | Returns the array of field settings. | |
FieldItemBase:: |
public static | function |
Informs the plugin that a dependency of the field will be deleted. Overrides FieldItemInterface:: |
1 |
FieldItemBase:: |
public | function |
Defines custom post-save behavior for field values. Overrides FieldItemInterface:: |
2 |
FieldItemBase:: |
public | function |
Returns a form for the storage-level settings. Overrides FieldItemInterface:: |
8 |
FieldItemBase:: |
public static | function |
Returns a settings array in the field type's canonical representation. Overrides FieldItemInterface:: |
2 |
FieldItemBase:: |
public static | function |
Returns a settings array that can be stored as a configuration value. Overrides FieldItemInterface:: |
2 |
FieldItemBase:: |
public | function |
Returns a renderable array for a single field item. Overrides FieldItemInterface:: |
|
FieldItemBase:: |
protected | function |
Different to the parent Map class, we avoid creating property objects as
far as possible in order to optimize performance. Thus we just update
$this->values if no property object has been created yet. Overrides Map:: |
|
FieldItemBase:: |
public | function |
Constructs a TypedData object given its definition and context. Overrides TypedData:: |
1 |
FieldItemBase:: |
public | function |
Magic method: Gets a property value. Overrides FieldItemInterface:: |
2 |
FieldItemBase:: |
public | function |
Magic method: Determines whether a property is set. Overrides FieldItemInterface:: |
|
FieldItemBase:: |
public | function |
Magic method: Sets a property value. Overrides FieldItemInterface:: |
1 |
FieldItemBase:: |
public | function |
Magic method: Unsets a property. Overrides FieldItemInterface:: |
|
FileLinkItem:: |
protected | property | The entity type manager service. | |
FileLinkItem:: |
protected | property | The exception throw by the the last HTTP client request, if any. | |
FileLinkItem:: |
protected | property | The HTTP client service. | |
FileLinkItem:: |
protected | property | The HTTP response of the last client request, if any. | |
FileLinkItem:: |
public | function |
Clears a previous stored Guzzle exception. Overrides FileLinkInterface:: |
|
FileLinkItem:: |
public | function |
Clears a previous stored HTTP response. Overrides FileLinkInterface:: |
|
FileLinkItem:: |
public static | function |
Defines the field-level settings for this plugin. Overrides LinkItem:: |
|
FileLinkItem:: |
public | function |
Returns a form for the field-level settings. Overrides LinkItem:: |
|
FileLinkItem:: |
public static | function |
Generates placeholder field values. Overrides LinkItem:: |
|
FileLinkItem:: |
protected | function | Returns the entity type manager service. | |
FileLinkItem:: |
public | function |
Gets the last Guzzle client exception. Overrides FileLinkInterface:: |
|
FileLinkItem:: |
public | function |
Get file format. Overrides FileLinkInterface:: |
|
FileLinkItem:: |
protected | function | Returns the HTTP client service. | |
FileLinkItem:: |
public | function |
Gets the latest stored HTTP response. Overrides FileLinkInterface:: |
|
FileLinkItem:: |
public | function |
Get raw file size. Overrides FileLinkInterface:: |
|
FileLinkItem:: |
protected | function | Check whereas given response is supported by field type. | |
FileLinkItem:: |
public | function |
Defines custom presave behavior for field values. Overrides FieldItemBase:: |
|
FileLinkItem:: |
public static | function |
Defines field item properties. Overrides LinkItem:: |
|
FileLinkItem:: |
public static | function |
Returns the schema for the field. Overrides LinkItem:: |
|
FileLinkItem:: |
public | function |
Sets the exception throw by the last HTTP client request. Overrides FileLinkInterface:: |
|
FileLinkItem:: |
public | function |
Sets the latest HTTP response. Overrides FileLinkInterface:: |
|
LinkItem:: |
public | function |
Gets the URL object. Overrides LinkItemInterface:: |
|
LinkItem:: |
public | function |
Determines whether the data structure is empty. Overrides Map:: |
|
LinkItem:: |
public | function |
Determines if a link is external. Overrides LinkItemInterface:: |
|
LinkItem:: |
public static | function |
Returns the name of the main property, if any. Overrides FieldItemBase:: |
|
LinkItem:: |
public | function |
Sets the data value. Overrides FieldItemBase:: |
|
LinkItemInterface:: |
constant | Specifies whether the field supports only external URLs. | ||
LinkItemInterface:: |
constant | Specifies whether the field supports both internal and external URLs. | ||
LinkItemInterface:: |
constant | Specifies whether the field supports only internal URLs. | ||
Map:: |
protected | property |
The data definition. Overrides TypedData:: |
|
Map:: |
protected | property | The array of properties. | |
Map:: |
protected | property | An array of values for the contained properties. | |
Map:: |
public | function |
Applies the default value. Overrides TypedData:: |
4 |
Map:: |
public | function |
Gets a property object. Overrides ComplexDataInterface:: |
|
Map:: |
public | function | ||
Map:: |
public | function |
Gets an array of property objects. Overrides ComplexDataInterface:: |
|
Map:: |
public | function |
Returns a string representation of the data. Overrides TypedData:: |
|
Map:: |
public | function |
Gets the data value. Overrides TypedData:: |
1 |
Map:: |
public | function |
Overrides TraversableTypedDataInterface:: |
4 |
Map:: |
public | function |
Sets a property value. Overrides ComplexDataInterface:: |
|
Map:: |
public | function |
Returns an array of all property values. Overrides ComplexDataInterface:: |
1 |
Map:: |
public | function | Magic method: Implements a deep clone. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
TypedData:: |
protected | property | The property name. | |
TypedData:: |
protected | property | The parent typed data object. | |
TypedData:: |
public static | function |
Constructs a TypedData object given its definition and context. Overrides TypedDataInterface:: |
|
TypedData:: |
public | function |
Gets a list of validation constraints. Overrides TypedDataInterface:: |
9 |
TypedData:: |
public | function |
Gets the data definition. Overrides TypedDataInterface:: |
|
TypedData:: |
public | function |
Returns the name of a property or item. Overrides TypedDataInterface:: |
|
TypedData:: |
public | function |
Returns the parent data structure; i.e. either complex data or a list. Overrides TypedDataInterface:: |
|
TypedData:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
|
TypedData:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
TypedData:: |
public | function |
Returns the property path of the data. Overrides TypedDataInterface:: |
|
TypedData:: |
public | function |
Returns the root of the typed data tree. Overrides TypedDataInterface:: |
|
TypedData:: |
public | function |
Sets the context of a property or item via a context aware parent. Overrides TypedDataInterface:: |
|
TypedData:: |
public | function |
Validates the currently set data value. Overrides TypedDataInterface:: |
|
TypedDataTrait:: |
protected | property | The typed data manager used for creating the data types. | |
TypedDataTrait:: |
public | function | Gets the typed data manager. | 2 |
TypedDataTrait:: |
public | function | Sets the typed data manager. | 2 |