datafield-1.x-dev/src/Plugin/DataField/FieldWidget/FileWidget.php
src/Plugin/DataField/FieldWidget/FileWidget.php
<?php
namespace Drupal\datafield\Plugin\DataField\FieldWidget;
use Drupal\Component\Render\PlainTextOutput;
use Drupal\Core\Field\Attribute\FieldWidget;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\datafield\Plugin\DataFieldWidgetInterface;
use Drupal\file\Entity\File;
use Symfony\Component\Validator\ConstraintViolationInterface;
/**
* Plugin implementation of the 'file_generic' widget.
*/
#[FieldWidget(
id: 'managed_file',
label: new TranslatableMarkup('Uploading and saving file'),
field_types: ['file', 'entity_reference'],
)]
class FileWidget implements DataFieldWidgetInterface {
use StringTranslationTrait;
/**
* {@inheritdoc}
*/
public function getFormElement(&$element, $item = NULL, $setting = []) {
$fieldName = str_replace('field_', '', $element['#field_name']);
if (empty($element["#field_settings"]["file_directory"])) {
$element["#field_settings"]["file_directory"] = $fieldName;
}
if (empty($element["#field_settings"]["uri_scheme"])) {
$element["#field_settings"]["uri_scheme"] = 'public';
}
$element['#upload_location'] = self::doGetUploadLocation($element["#field_settings"], $setting);
$element['#process_default_value'] = FALSE;
if (!empty($element["#default_value"])) {
if (is_object($element["#default_value"])) {
$element["#default_value"] = [$element["#default_value"]->id()];
}
if (is_numeric($element["#default_value"])) {
$element["#default_value"] = [$element["#default_value"]];
}
}
if (!empty($element["#field_settings"]["file_extensions"])) {
$setting["file_extensions"] = str_replace(
[',', ' '], ' ',
$element["#field_settings"]["file_extensions"]
);
$element['#upload_validators'] = [
'FileExtension' => ['extensions' => $setting["file_extensions"]],
];
}
if (!empty($element['#field_parents'])) {
$element['#parents'] = array_merge($element['#field_parents'], [
$element['#field_name'],
$element['#delta'],
$element["#field_storage"]["name"],
]);
}
else {
$element['#parents'] = [
$element['#field_name'],
$element['#delta'],
$element["#field_storage"]["name"],
];
}
$element['#progress_indicator'] = 'throbber';
}
/**
* Determines the URI for a file field.
*
* @param array $settings
* The array of field settings.
* @param array $data
* An array of token objects to pass to Token::replace().
*
* @return string
* An unsanitized file directory URI with tokens replaced. The result of
* the token replacement is then converted to plain text and returned.
*
* @see \Drupal\Core\Utility\Token::replace()
*/
protected static function doGetUploadLocation(array $settings, $data = []) {
$destination = trim($settings['file_directory'], '/');
// Replace tokens. As the tokens might contain HTML we convert it to plain
// text.
$destination = PlainTextOutput::renderFromHtml(\Drupal::token()->replace($destination, $data));
return $settings['uri_scheme'] . '://' . $destination;
}
/**
* {@inheritdoc}
*/
public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, FormStateInterface $form_state): bool {
return FALSE;
}
/**
* {@inheritdoc}
*/
public function massageFormValues($value, array $form, FormStateInterface $form_state) {
$entityType = $form["#field_settings"]["entity_reference_type"] ?? 'file';
if (in_array($entityType, ['file', 'image'], TRUE) &&
is_array($value) &&
isset($value[0])) {
$fid = (int) $value[0];
if ($fid > 0 && ($file = File::load($fid)) && !$file->get('status')->value) {
$file->set('status', TRUE)->save();
}
return $fid;
}
return $value;
}
}
