Question

I'm triggering a Feeds import in a custom module I made. I need to set a value of a blank source in that code because that value is not in the source file (in this case is a xml). Is it possible to do this?

Below is the code I have.

$path = $url . '/path_to_my_file/myfile.xml';
$feeds_source = feeds_source($feeds_importer);
$feeds_config = $feeds_source->getConfigFor($feeds_source->importer->fetcher);

$file_exists = get_headers($path, 1);

# check if file exists:     
if ($file_exists[0] == 'HTTP/1.1 200 OK') {
    $feeds_config['source'] = $path;

    $config = array(
        'process_in_background' => TRUE,
    );

    $feeds_source->setConfigFor($feeds_source->importer->fetcher, $feeds_config);
    $feeds_source->importer->addConfig($config);
    $feeds_source->save();
    $feeds_source->startImport();

    while (FEEDS_BATCH_COMPLETE != $feeds_source->import());
}

UPDATE:

Below is a more complete code. I have 3 functions. The first one is the original but one. Notice tha I get the $VALUETOPASS variable from the function arguments.

The other 2 functions are the ones rooby suggested. The problem is how to have the $VALUETOPASS in the last function. At this moment I only need that.

function MYMODULE_CustomImport($VALUETOPASS) {
  $path = $url . '/path_to_my_file/myfile.xml';
  $feeds_source = feeds_source($feeds_importer);
  $feeds_config = $feeds_source->getConfigFor($feeds_source->importer->fetcher);

  $file_exists = get_headers($path, 1);

  # check if file exists:       
  if ($file_exists[0] == 'HTTP/1.1 200 OK') {
    $feeds_config['source'] = $path;

    $config = array(
        'process_in_background' => TRUE,
    );

    $feeds_source->setConfigFor($feeds_source->importer->fetcher, $feeds_config);
    $feeds_source->importer->addConfig($config);
    $feeds_source->save();
    $feeds_source->startImport();

    while (FEEDS_BATCH_COMPLETE != $feeds_source->import());
  }

function MYMODULE_feeds_processor_targets_alter(array &$targets, $entity_type, $bundle) {
  // Set a custom value setter callback for the my field on my node type.
  if ($entity_type == 'node' && $bundle == 'my_bundle') {
    if (isset($targets['my_field'])) {
      $targets['my_field']['callback'] = 'MYMODULE_set_custom_field_value';
    }
  }
}

function MYMODULE_set_custom_field_value(FeedsSource $source, $entity, $target, array $values, array $mapping) {
  $xml = simplexml_load_file($url . $VALUETOPASS . '/api/xml');
  $multijob_array = json_decode(json_encode((array)$xml), TRUE);

  if (isset($multijob_array['action'][2]['cause']['upstreamBuild'])) {
    $multijob_build = $multijob_array['action'][2]['cause']['upstreamBuild'];
  } else {
    $multijob_build = '';
  }

  $entity->{$target}[$entity->language][0]['value'] = $value;
}
Was it helpful?

Solution

In the code where you run the importer you can only alter the field mapping.

To modify the field mapping configuration at that point to add custom data (you can also do things like remove fields from the mapping here):

// Load the importer.
$importer_id = 'my_importer';
$feeds_source = feeds_source($importer_id);
// Get the current field mappings.
$field_mappings = $feeds_source->importer->processor->getMappings();

foreach ($field_mappings as &$mapping) {
  // Add an arbitrary value to the mapping of my_field for
  // use later in the processor target callback.
  if ($mapping['target'] == 'my_field') {
    // Your logic goes here to populate this.
    $mapping['my_custom_value'] = 'My custom value';
  }
}

// Set the new field mappings.
$feeds_source->importer->processor->addConfig(array('mappings' => $field_mappings));
// Save the new field mappings.
$feeds_source->save();
// The previous call to FeedsProcessor::getMappings() cached
// the mapping, so we need to clear that before we run the import.
drupal_static_reset('FeedsProcessor::getMappings');

// Run the import.
$feeds_source->startImport();
while (FEEDS_BATCH_COMPLETE != $feeds_source->import());

Then to change the actual value that goes into the field, you have to do that at import time, when feeds is getting the value from the source and saving it to the target.

To do that you can implement hook_feeds_processor_targets_alter(), like this:

/**
 * Implements hook_feeds_processor_targets_alter().
 */
function my_module_feeds_processor_targets_alter(array &$targets, $entity_type, $bundle) {
  // Set a custom value setter callback for the my field on my node type.
  if ($entity_type == 'node' && $bundle == 'my_node_type') {
    if (isset($targets['my_field'])) {
      $targets['my_field']['callback'] = 'my_module_set_custom_field_value';
    }
  }
}

/**
 * Custom feeds target setter callback.
 */
function my_module_set_custom_field_value(FeedsSource $source, $entity, $target, array $values, array $mapping) {
  // Set the field value to our custom value if it's there.
  if (!empty($mapping['my_custom_value'])) {
    $entity->{$target}[$entity->language][0]['value'] = $mapping['my_custom_value'];
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with drupal.stackexchange
scroll top