I have created a custom field for advice it has four subfields : title, body, url, image.
Everything works perfectly except the image is deleted after a certain period of time because it was not added to the file_usage table. How do I add it to the table?
The code for the custom field:
<?php namespace DrupalindustryPluginFieldFieldType; use DrupalComponentRenderPlainTextOutput; use DrupalComponentUtilityBytes; use DrupalCoreFieldFieldItemBase; use DrupalCoreFieldFieldStorageDefinitionInterface; use DrupalCoreFormFormStateInterface; use DrupalCoreStreamWrapperStreamWrapperInterface; use DrupalCoreTypedDataDataDefinition; use DrupalCoreStringTranslationTranslatableMarkup; /** * Provides a field type of baz. * * @FieldType( * id = "advice", * label = @Translation("advice field"), * default_formatter = "adviceFormatter", * default_widget = "adviceWidget", * ) */ class adviceField extends FieldItemBase { public static function schema(FieldStorageDefinitionInterface $field_definition) { return [ // columns contains the values that the field will store 'columns' => [ // List the values that the field will save. This // field will only save a single value, 'value' 'title' => [ 'type' => 'varchar', 'length' => '256', 'not null' => FALSE, ], 'image' => [ 'type' => 'int', 'description' => 'upload image', 'unsigned' => TRUE, 'not null' => FALSE, ], 'body' => [ 'type' => 'text', 'size' => 'normal', 'not null' => FALSE, ], 'url' => [ 'type' => 'varchar', 'length' => '256', 'not null' => FALSE, ], ], 'foreign keys' => [ 'image' => [ 'table' => 'file_managed', 'columns' => ['image' => 'fid'], ], ], 'indexes' => [] ]; } public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) { $properties = []; $properties['title'] = DataDefinition::create('string') ->setLabel(t('title')); $properties['body'] = DataDefinition::create('string') ->setLabel(t('body')); $properties['iamge'] = DataDefinition::create('integer') ->setLabel(t('iamge')); $properties['url'] = DataDefinition::create('string') ->setLabel(t('url')); return $properties; } public function isEmpty() { $isEmpty = empty($this->get('title')->getValue()) && empty($this->get('body')->getValue()->value) && $this->get('iamge')->getValue() == [] && empty($this->get('url')->getValue()); return $isEmpty; } /** * {@inheritdoc} */ public static function defaultStorageSettings() { return [ 'target_type' => 'file', 'display_field' => FALSE, 'display_default' => FALSE, 'uri_scheme' => Drupal::config('system.file')->get('default_scheme'), ] + parent::defaultStorageSettings(); } /** * {@inheritdoc} */ public static function defaultFieldSettings() { return [ 'file_extensions' => 'png gif jpg jpeg', 'file_directory' => '[date:custom:Y]-[date:custom:m]', 'max_filesize' => '10MB', 'description_field' => 0, ] + parent::defaultFieldSettings(); } /** * {@inheritdoc} */ public function fieldSettingsForm(array $form, FormStateInterface $form_state) { $element = []; $settings = $this->getSettings(); // Make the extension list a little more human-friendly by comma-separation. $extensions = null; if (isset($settings['file_extensions'])) { $extensions = str_replace(' ', ', ', $settings['file_extensions']); } $element['file_extensions'] = [ '#type' => 'textfield', '#title' => t('Allowed file extensions'), '#default_value' => $extensions, '#description' => t('Separate extensions with a space or comma and do not include the leading dot.'), '#element_validate' => [[get_class($this), 'validateExtensions']], '#weight' => 1, '#maxlength' => 256, // By making this field required, we prevent a potential security issue // that would allow files of any type to be uploaded. '#required' => TRUE, ]; $file_directory = null; if (isset($settings['file_directory'])) { $file_directory = $settings['file_directory']; } $element['file_directory'] = [ '#type' => 'textfield', '#title' => t('File directory'), '#default_value' => $file_directory, '#description' => t('Optional subdirectory within the upload destination where files will be stored. Do not include preceding or trailing slashes.'), '#element_validate' => [[get_class($this), 'validateDirectory']], '#weight' => 3, ]; $max_filesize = null; if (isset($settings['max_filesize'])) { $max_filesize = $settings['max_filesize']; } $element['max_filesize'] = [ '#type' => 'textfield', '#title' => t('Maximum upload size'), '#default_value' => $max_filesize, '#description' => t('Enter a value like "512" (bytes), "80 KB" (kilobytes) or "50 MB" (megabytes) in order to restrict the allowed file size. If left empty the file sizes will be limited only by PHP's maximum post and file upload sizes (current limit <strong>%limit</strong>).', ['%limit' => format_size(10000000)]), '#size' => 10, '#element_validate' => [[get_class($this), 'validateMaxFilesize']], '#weight' => 5, ]; return $element; } /** * {@inheritdoc} */ public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) { $element = []; $element['#attached']['library'][] = 'file/drupal.file'; $element['display_field'] = [ '#type' => 'checkbox', '#title' => t('Enable <em>Display</em> field'), '#default_value' => $this->getSetting('display_field'), '#description' => t('The display option allows users to choose if a file should be shown when viewing the content.'), ]; $element['display_default'] = [ '#type' => 'checkbox', '#title' => t('Files displayed by default'), '#default_value' => $this->getSetting('display_default'), '#description' => t('This setting only has an effect if the display option is enabled.'), '#states' => [ 'visible' => [ ':input[name="settings[display_field]"]' => ['checked' => TRUE], ], ], ]; $scheme_options = Drupal::service('stream_wrapper_manager')->getNames(StreamWrapperInterface::WRITE_VISIBLE); $element['uri_scheme'] = [ '#type' => 'radios', '#title' => t('Upload destination'), '#options' => $scheme_options, '#default_value' => $this->getSetting('uri_scheme'), '#description' => t('Select where the final files should be stored. Private file storage has significantly more overhead than public files, but allows restricted access to files within this field.'), '#disabled' => $has_data, ]; return $element; } /** * Determines the URI for a file field. * * @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 DrupalCoreUtilityToken::replace() */ public function getUploadLocation($data = []) { return static::doGetUploadLocation($this->getSettings(), $data); } /** * 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 DrupalCoreUtilityToken::replace() */ protected static function doGetUploadLocation(array $settings, $data = []) { if (isset($settings['file_directory'])) { $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; } else { return 'public://advice/'; } } /** * Retrieves the upload validators for a file field. * * @return array * An array suitable for passing to file_save_upload() or the file field * element's '#upload_validators' property. */ public function getUploadValidators() { $validators = []; $settings = $this->getSettings(); // Cap the upload size according to the PHP limit. $max_filesize = Bytes::toInt(1000000); if (!empty($settings['max_filesize'])) { $max_filesize = min($max_filesize, Bytes::toInt($settings['max_filesize'])); } // There is always a file size limit due to the PHP server limit. $validators['file_validate_size'] = [$max_filesize]; // Add the extension check if necessary. if (isset($settings['file_extensions']) && !empty($settings['file_extensions'])) { $validators['file_validate_extensions'] = [$settings['file_extensions']]; } return $validators; } }
<?php namespace DrupalindustryPluginFieldFieldFormatter; use DrupalCoreFieldFieldItemListInterface; use DrupalCoreFieldFormatterBase; use Drupal; /** * Plugin implementation of the 'AddressDefaultFormatter' formatter. * * @FieldFormatter( * id = "adviceFormatter", * label = @Translation("advice"), * field_types = { * "advice","string","integer" * } * ) */ class adviceFormatter extends FormatterBase { public function viewElements(FieldItemListInterface $items, $langcode) { $elements = []; foreach ($items as $delta => $item) { $body = json_decode($item->body); if (empty($item->image)) { $url = ""; } else { $file = DrupalfileEntityFile::load($item->image); if ($file != null) { $uri = $file->getFileUri(); $url = DrupalCoreUrl::fromUri(file_create_url($uri))->toString(); } else { $url = ""; } } $elements[$delta] = [ '#type' => 'markup', '#markup' => '<div class="card-body row"> <div class="col-md-3" style="text-align: center;"> <img src="' . $url . '" class="advice-img"> </div> <div class="col-md-9"> <h4 style=" text-align: left;">' . $item->title . '</h4>' . $body->value . ' <div class="_clickMore" style="text-align: left;"> <a href="' . $item->url . '" target="_blank">Visit Website</a> </div> <br><br> <br> </div> </div>']; } return $elements; } }
<?php namespace DrupalindustryPluginFieldFieldWidget; use Drupal; use DrupalComponentUtilityBytes; use DrupalCoreFieldFieldItemListInterface; use DrupalCoreFieldWidgetBase; use DrupalCoreFormFormStateInterface; /** * Plugin implementation of the 'AddressDefaultWidget' widget. * * @FieldWidget( * id = "adviceWidget", * label = @Translation("advice field"), * field_types = { * "advice","string","integer" * } * ) */ class adviceFieldWidget extends WidgetBase { public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { $form['#attributes']['enctype'] = 'multipart/form-data'; $element['title'] = [ '#type' => 'textfield', '#title' => t('title'), '#default_value' => isset($items[$delta]->title) ? $items[$delta]->title : '', '#empty_value' => '', '#placeholder' => t('Title'), ]; $element['url'] = [ '#type' => 'textfield', '#title' => t('url'), '#default_value' => isset($items[$delta]->url) ? $items[$delta]->url : '', '#empty_value' => '', '#placeholder' => t('url'), ]; if (isset($items[$delta]->body)) { $body = json_decode($items[$delta]->body); } $element['body'] = [ '#type' => 'text_format', '#title' => t('body'), '#default_value' => isset($body) ? $body->value : '', '#format' => isset($body) ? $body->format : 'basic_html', '#empty_value' => '', '#placeholder' => t('body'), '#base_type' => 'textarea', ]; // City $element['image'] = [ '#type' => 'managed_file', '#title' => t('image'), '#upload_location' => $items[$delta]->getUploadLocation(), '#upload_validators' => $items[$delta]->getUploadValidators(), '#empty_value' => '', '#default_value' => isset($items[$delta]->image) ? [$items[$delta]->image] : [], ]; return $element; } public function massageFormValues(array $values, array $form, FormStateInterface $form_state) { foreach ($values as $index => $value) { $values[$index]['body'] = json_encode($value['body']); if (isset($value['image'][0])){ unset($values[$index]['image']); $values[$index]['image'] = $value['image'][0]; // $file = DrupalfileEntityFile::load($value['image'][0]); // Drupal::service('file.usage')->add($file, 'industry', 'node', $file->id()); } } return $values; } public static function getFileId($target) { $fid = null; if (!empty($target) && is_array($target) && !empty($target[0])) { if ( is_int($target[0]) ) { $fid = $target[0]; } else { $fid = (int)$target[0]; } } elseif (is_int($target)) { $fid = $target; } return $fid; } }