Score:0

save file in file_usage of custom field

uy flag

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 Drupal\industry\Plugin\Field\FieldType;

use Drupal\Component\Render\PlainTextOutput;
use Drupal\Component\Utility\Bytes;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StreamWrapper\StreamWrapperInterface;
use Drupal\Core\TypedData\DataDefinition;

use Drupal\Core\StringTranslation\TranslatableMarkup;


/**
 * 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 \Drupal\Core\Utility\Token::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 \Drupal\Core\Utility\Token::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 Drupal\industry\Plugin\Field\FieldFormatter;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
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 = \Drupal\file\Entity\File::load($item->image);
        if ($file != null) {
          $uri = $file->getFileUri();

          $url = \Drupal\Core\Url::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"> &nbsp;
                </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 Drupal\industry\Plugin\Field\FieldWidget;

use Drupal;
use Drupal\Component\Utility\Bytes;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * 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 = \Drupal\file\Entity\File::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;
  }




}
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.