You are here

abstract class MigrateFileFieldBaseHandler in Migrate 7.2

The next generation of file field handler. This class focuses on the file field itself, and offloads understanding of obtaining the actual file and dealing with the file entity to an embedded MigrateFileInterface instance.

Hierarchy

Expanded class hierarchy of MigrateFileFieldBaseHandler

File

plugins/destinations/fields.inc, line 624
Support for processing entity fields

View source
abstract class MigrateFileFieldBaseHandler extends MigrateFieldHandler {

  /**
   * Implementation of MigrateFieldHandler::fields().
   *
   * @param $type
   *  The file field type - 'file', 'image', etc.
   * @param $instance
   *  Instance info for the field.
   * @param Migration $migration
   *  The migration context for the parent field. We can look at the mappings
   *  and determine which subfields are relevant.
   *
   * @return array
   */
  public function fields($type, $instance, $migration = NULL) {
    $fields = array(
      'file_class' => t('Option: <a href="@doc">Implementation of MigrateFile to use</a>', array(
        '@doc' => 'http://drupal.org/node/1540106#file_class',
      )),
    );
    $field = field_info_field($instance['field_name']);
    if (field_is_translatable($instance['entity_type'], $field)) {
      $fields['language'] = t('Subfield: Language for the field');
    }

    // If we can identify the file class mapped to this field, pick up the
    // subfields specific to that class.
    if ($migration) {
      $field_mappings = $migration
        ->getFieldMappings();
      $class_mapping = $instance['field_name'] . ':file_class';
      if (isset($field_mappings[$class_mapping])) {
        $mapping = $field_mappings[$class_mapping];
        $file_class = $mapping
          ->getDefaultValue();
      }
    }
    if (empty($file_class)) {
      $file_class = 'MigrateFileUri';
    }
    $fields += call_user_func(array(
      $file_class,
      'fields',
    ));
    return $fields;
  }

  /**
   * Implementation of MigrateFieldHandler::prepare().
   *
   * Prepare file data for saving as a Field API file field.
   *
   * @return array
   *  Field API array suitable for inserting in the destination object.
   */
  public function prepare($entity, array $field_info, array $instance, array $values) {
    if (isset($values['arguments'])) {
      $arguments = $values['arguments'];
      unset($values['arguments']);
    }
    else {
      $arguments = array();
    }
    $default_language = $this
      ->getFieldLanguage($entity, $field_info, $arguments);
    $migration = Migration::currentMigration();

    // One can override the source class via CLI or drushrc.php (the
    // option is named file_function for historical reasons).
    if ($migration
      ->getOption('file_function')) {
      $file_class = $migration
        ->getOption('file_function');
    }
    elseif (!empty($arguments['file_class'])) {
      $file_class = $arguments['file_class'];
    }
    else {
      $file_class = 'MigrateFileUri';
    }

    // If a destination directory
    // (relative to the Drupal public files directory) is not
    // explicitly provided, use the default for the field.
    if (empty($arguments['destination_dir'])) {
      $arguments['destination_dir'] = $this
        ->destinationDir($field_info, $instance);
    }
    $return = array();

    // Note that what $value represents depends on the file class -
    // MigrateFileUri expects a filespec/URI, MigrateFileFid expects a file ID,
    // etc.
    foreach ($values as $delta => $value) {
      if ($value) {

        // Handle potentially multiple arguments.
        $instance_arguments = array();
        foreach ($arguments as $key => $argument) {

          // For a scalar argument, pass it directly.
          if (!is_array($argument)) {
            $instance_arguments[$key] = $argument;
          }
          else {
            if (isset($argument[$delta])) {
              $instance_arguments[$key] = $argument[$delta];
            }
            else {
              $migration
                ->saveMessage(t('No data for subfield %key at row %delta for field %field', array(
                '%key' => $key,
                '%delta' => $delta,
                '%field' => $field_info['field_name'],
              )), Migration::MESSAGE_WARNING);
            }
          }
        }

        // If the parent entity doesn't have an explicit uid, give ownership
        // to the anonymous account.
        $owner = isset($entity->uid) ? $entity->uid : 0;

        // Call the MigrateFileInterface implementation to do the real work.
        $source = new $file_class($instance_arguments);
        $file = $source
          ->processFile($value, $owner);

        // Assuming we got back a valid file ID, build the proper field
        // array out of it. We assume that if we did not get back a fid, the
        // MigrateFile class has saved a message indicating why.
        if ($file) {
          $field_array = array(
            'fid' => $file->fid,
          );
          $language = isset($instance_arguments['language']) ? $instance_arguments['language'] : $default_language;
          if (is_array($language)) {
            $language = $language[$delta];
          }
          $return[$language][] = $this
            ->buildFieldArray($field_array, $instance_arguments, $delta);
        }
      }
    }
    return $return;
  }

  /**
   * Determine where the migrated file should go.
   *
   * @param $field_info
   *  Field API info on the general field.
   * @param $instance
   *  Field API info on the field instance for this entity type.
   *
   * @return string
   *  Directory relative to the Drupal public files directory.
   */
  protected function destinationDir($field_info, $instance) {

    // Only apply for file/image types
    if (isset($instance['settings']['file_directory'])) {
      $destination_dir = file_field_widget_uri($field_info, $instance);
    }
    else {
      $destination_dir = 'public://';
    }
    return $destination_dir;
  }

  /**
   * Add any type-specific subfields to a file field array.
   *
   * @param $field_array
   *  The field array so far (generally will just contain a fid).
   * @param $arguments
   *  Array of arguments passed to the field handler, from which we'll extract
   *  our own subfields.
   * @param $delta
   *  Index of field values being worked on, for pulling the corresponding
   *  subfield values if we have an array of them.
   */
  protected abstract function buildFieldArray($field_array, $arguments, $delta);

}

Members

Namesort descending Modifiers Type Description Overrides
MigrateFieldHandler::getFieldLanguage function Determine the language of the field.
MigrateFileFieldBaseHandler::buildFieldArray abstract protected function Add any type-specific subfields to a file field array. 2
MigrateFileFieldBaseHandler::destinationDir protected function Determine where the migrated file should go.
MigrateFileFieldBaseHandler::fields public function Implementation of MigrateFieldHandler::fields(). 2
MigrateFileFieldBaseHandler::prepare public function Implementation of MigrateFieldHandler::prepare().
MigrateHandler::$dependencies protected property List of other handler classes which should be invoked before the current one.
MigrateHandler::$typesHandled protected property List of "types" handled by this handler. Depending on the kind of handler, these may be destination types, field types, etc.
MigrateHandler::getDependencies public function
MigrateHandler::getTypesHandled public function
MigrateHandler::handlesType public function Does this handler handle the given type? 1
MigrateHandler::registerTypes protected function Register a list of types handled by this class
MigrateHandler::__construct abstract public function 11