1

I have troubles adding a simple additional properties (like alt or title) to the image field type.

In the .module file I defined an alternative class for the image field.

function image_video_link_field_info_alter(&$info) {
  // Change the default widget for fields of type 'image'.
  if (isset($info['image'])) {
    $info['image']['class'] = '\Drupal\image_video_link\LinkedImageItem';
    #$info['image']['column_groups']['videolink'] = ['label' => t('Link to a video.')];
  }
}

I extended the ImageItem class with some additional properties.

/**
 * @file
 * Contains \Drupal\image_video_link\LinkedImageItem.
 */

namespace Drupal\image_video_link;

use Drupal\image\Plugin\Field\FieldType\ImageItem;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\DataDefinition;

/**
 * Extends the default PathItem implementation to generate aliases.
 */
class LinkedImageItem extends ImageItem {
  /**
   * {@inheritdoc}
   */
  public static function defaultStorageSettings() {
    $settings = parent::defaultStorageSettings();
    $settings['default_image']['videolink'] = '';
    return $settings;
  }

  /**
   * {@inheritdoc}
   */
  public static function defaultFieldSettings() {
    $settings = parent::defaultFieldSettings();
    $settings['default_image']['videolink'] = '';
    return $settings;
  }

  /**
   * {@inheritdoc}
   */
  public static function schema(FieldStorageDefinitionInterface $field_definition) {
    $schema = parent::schema($field_definition);
    $schema['columns']['videolink'] = [
      'description' => "Link to a video.",
      'type' => 'varchar',
      'length' => 512,
    ];
    return $schema;
  }

  /**
   * {@inheritdoc}
   */
  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
    $properties = parent::propertyDefinitions($field_definition);

    $properties['videolink'] = DataDefinition::create('string')
      ->setLabel(t('Videolink'))
      ->setDescription(t("Link to a video on Vimeo."));

    return $properties;
  }
}

I believe I have to update the database in the .install file as I am getting the following error.

Undefined property: stdClass::$field_gallery_videolink

How do I do that? Is my method even valid?

  • Have a look at File Entity (fieldable files). It allows you to add 'custom fields' for files / media - including images. – JP Dippenaar Sep 16 '15 at 7:51
  • I already considered it, but this would require too much testing and would be simply an overkill, as I only need to extend the existing fieldtype. – alexej_d Sep 16 '15 at 20:08
  • Yes, you need to implement hook_update_N(). See this issue for reference drupal.org/node/2542748 – jonhattan Sep 19 '15 at 19:22
  • Would you care to give me a code example? I already have existing entities. Do I need to save them in an object and migrate them once the new field storage is set up? – alexej_d Sep 19 '15 at 20:31
  • Sorry, writing an example of the needed code is almost solving the job. You want to write a hook_update_N() to just add a new column (with a default value) to the table of all fields of the given type. So you need to get the list of fields, and perform $schema->addField('mytable1', 'newcol', $spec); See this change record (reachable from the previous link) drupal.org/node/2554097 and also this page on how to add columns to a table: drupal.org/node/2535384 – jonhattan Sep 20 '15 at 20:57
0

you should use hook_field_attach_update Hook Filed Attach Update

/**
 * Implements hook_field_attach_update().
*/
function mymodule_field_attach_update($entity_type, $entity) {
 // The other way around: you upload a new image on a node and enter    alt/title tags.
// Save alt and title text from the image field to the file entity,
// but ONLY if the file entity's alt/title fields are empty.
if ($entity_type == 'node') {  
 list(, , $bundle) = entity_extract_ids($entity_type, $entity);
// Examine every image field instance attached to this entity's bundle.
 $instances = array_intersect_key(field_info_instances($entity_type,$bundle), _file_entity_get_fields_by_type('image'));
foreach ($instances as $field_name => $instance) {
  if (!empty($entity->{$field_name})) {
    foreach ($entity->{$field_name} as $langcode => $items) {
      foreach ($items as $delta => $item) {
        $file = file_load($item['fid']);
        if ($file) {
          if (isset($file->field_file_image_alt_text) && empty($file->field_file_image_alt_text[$langcode][0]['value'])) { 
            $file->field_file_image_alt_text[$langcode][0]['value'] = $item['alt'];
          }
          if (isset($file->field_file_image_title_text) && empty($file->field_file_image_title_text[$langcode][0]['value'])) { 
            $file->field_file_image_title_text[$langcode][0]['value'] = $item['title'];
          }
        }
        field_attach_update('file', $file);
      }
    }
  }
  }
 }
}
  • This does not relate to drupal 8... – alexej_d Sep 15 '15 at 11:28
  • please check this link api.hostdog.eu/api/drupal-8/… – Kamal Oberoi Sep 15 '15 at 11:38
  • field api for 8 drupalcontrib.org/api/drupal/… – Kamal Oberoi Sep 15 '15 at 11:41
  • You should check the actual codebase. This hook does not exist anymore – alexej_d Sep 15 '15 at 11:42
  • I know there is a field API but I would like an answer to my question, that's why I opened the thread. I need someone to give me a hint what to do with the error and how to add the db column if it is even needed – alexej_d Sep 15 '15 at 11:45
0

I know this is a older issue but I found it when trying to do the same. Still for this exactly case maybe answer from xxx would be also helpful.

After it took me a while to figure out how to do it I wanted to share this example. Only thing needs to change is the first few lines.

/**
 * Add new property to all fields of type XXX.
 */
function XXX_update_80YY() {
  $field_type = 'XXX';
  $new_properties = array(
    'PROPERTY_NAME' => array(
      'description' => 'PROPERTY DESCRIPTION',
      'type' => 'varchar',
      'length' => 255,
    ),
  );

  $definition_update_manager = \Drupal::entityDefinitionUpdateManager();
  /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $field_manager */
  $field_manager = \Drupal::service('entity_field.manager');
  /** @var \Drupal\Core\Entity\EntityTypeManager $entity_type_manager */
  $entity_type_manager = \Drupal::service('entity_type.manager');
  $field_map = $field_manager->getFieldMapByFieldType($field_type);
  $schema = Database::getConnection()->schema();
  foreach ($field_map as $entity_type_id => $fields) {
    $field_manager->clearCachedFieldDefinitions();
    $storage_definitions = $field_manager->getFieldStorageDefinitions($entity_type_id);

    $storage = $entity_type_manager->getStorage($entity_type_id);
    /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
    $table_mapping = $storage->getTableMapping();

    foreach ($fields as $field_name => $field) {
      $storage_definition = $storage_definitions[$field_name];
      if (!empty($storage_definition)) {
        $column_names = $table_mapping->getColumnNames($field_name);
        $table_names = [ $table_mapping->getFieldTableName($field_name) ];

        if ($storage_definition->isRevisionable()) {
          $table_names[] = $table_mapping->getDedicatedRevisionTableName($storage_definition);
        }

        foreach ($table_names as $table_name) {
          foreach ($new_properties as $property_name => $property_spec) {
            if (!$schema->fieldExists($table_name, $column_names[$property_name])) {
              $schema->addField($table_name, $column_names[$property_name], $property_spec);
            }
          }
        }
        $definition_update_manager->updateFieldStorageDefinition($storage_definition);
      }
    }
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.