Рейтинг:0

save file in file_usage of custom field

флаг uy

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;
  }




}

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.